19 #include <fmt/format.h> 29 switch (inputDataType)
31 case DataType::Float16:
32 return DataType::Float16;
34 case DataType::Float32:
35 return DataType::Float32;
36 case DataType::QAsymmS8:
37 return DataType::Signed32;
38 case DataType::QAsymmU8:
39 return DataType::Signed32;
40 case DataType::QSymmS8:
41 return DataType::Signed32;
42 case DataType::QSymmS16:
43 return DataType::Signed32;
46 return DataType::Float32;
56 std::string to_string(T value)
58 std::ostringstream os;
64 void ValidatePointer(
const void* ptr, std::string
const& descName, std::string
const& paramName)
69 paramName +
" parameter must be set.");
74 void ValidateTensorShapesMatch(
const TensorInfo& first,
76 std::string
const& descName,
77 std::string
const& firstName,
78 std::string
const& secondName)
83 + firstName +
" & " + secondName +
" must have identical shapes");
88 void ValidateNumInputs(
const WorkloadInfo& workloadInfo, std::string
const& descName,
const unsigned int expectedSize)
93 ": Requires exactly " + to_string(expectedSize) +
"input(s). " +
99 void ValidateNumOutputs(
const WorkloadInfo& workloadInfo, std::string
const& descName,
const unsigned int expectedSize)
104 ": Requires exactly " + to_string(expectedSize) +
" output(s). " +
112 void ValidateTensorNumElements(
const TensorInfo& tensor,
113 std::string
const& descName,
114 unsigned int numElements,
115 std::string
const& tensorName)
121 tensorName +
" tensor.");
127 const std::string& descName, std::string
const& tensorName)
136 void ValidPerAxisQuantizedDataType(
const TensorInfo& tensor,
const std::string& descName,
const std::string& tensorName)
141 ": Expected data type which supports per-axis quantization scheme but got " +
147 void ValidateTensorQuantizationSpace(
const TensorInfo& first,
149 const std::string& descName,
150 std::string
const& firstName,
151 std::string
const& secondName)
163 if (firstDataType != secondDataType)
166 " must be of the same quantized type, " +
174 " must have the same quantization space, " +
183 void ValidateBiasTensorQuantization(
const TensorInfo& biasTensor,
186 const std::string& descName)
189 auto VerifyBiasQuantizationScale = [&descName](
float biasScale,
float expectedScale) ->
void 191 constexpr
float tolerance = 0.0001f;
192 if (std::abs(biasScale - expectedScale) > tolerance)
195 ARMNN_LOG(
warning) << std::setprecision(6) << descName <<
": Expected " << expectedScale <<
196 " for bias quantization scale (product of input and weight scales), but got " <<
197 biasScale <<
". Using scale provided.";
213 if (weightScales.size() != biasScales.size())
215 std::stringstream msg;
216 msg << descName <<
": Expected matching number of per-axis quantization scales for weights and bias, " 217 <<
"but got different values. This is currently unsupported: weights=" << weightScales.size()
218 <<
", biases=" << biasScales.size();
222 for (
size_t i = 0ul; i < biasScales.size(); ++i)
225 VerifyBiasQuantizationScale(biasScales[i], expectedScale);
237 void ValidateTensors(
const std::vector<ITensorHandle*>& vec,
238 unsigned int numExpected,
239 const std::string& descName,
240 const std::string& varName)
242 if (vec.empty() && numExpected > 0)
247 for (
unsigned int i = 0; i < numExpected; ++i)
257 void ValidateBroadcastTensorShapesMatch(
const TensorInfo& first,
260 std::string
const& descName,
261 std::string
const& firstName,
262 std::string
const& secondName)
269 + firstName +
" & " + secondName
270 +
" must have the same number of dimensions in order to be broadcasted");
273 std::vector<uint32_t> outputDims(numDims, 0u);
274 for (uint32_t i = 0; i < numDims; i++)
277 const bool dimsNotOne = (first.
GetShape()[i] != 1) && (second.
GetShape()[i] != 1);
278 if (dimsNotEqual && dimsNotOne)
284 TensorShape broadcastShape =
TensorShape(armnn::numeric_cast<unsigned int>(outputDims.size()), outputDims.data());
285 if (broadcastShape != output.
GetShape())
288 + firstName +
" & " + secondName
289 +
" does not match the output shape");
295 const std::vector<armnn::DataType>& supportedTypes,
296 std::string
const& descName)
298 auto iterator = std::find(supportedTypes.begin(), supportedTypes.end(), info.
GetDataType());
299 if (iterator == supportedTypes.end())
306 void ValidateTensorDataTypesMatch(
const TensorInfo& first,
308 std::string
const& descName,
309 std::string
const& firstName,
310 std::string
const& secondName)
315 " must have identical data types.");
320 void ValidateTensorNumElementsMatch(
const TensorInfo& first,
322 std::string
const& descName,
323 std::string
const& firstName,
324 std::string
const& secondName)
329 " must have the same number of elements.");
333 void ValidateWeightDataType(
const TensorInfo& inputInfo,
335 const std::string& descName)
340 const std::vector<DataType> validTypes =
347 ValidateDataTypes(weightInfo, validTypes, descName);
351 ValidateTensorDataTypesMatch(inputInfo, weightInfo, descName,
"input",
"weight");
355 void ValidatePerAxisQuantizationDimension(
const TensorInfo& tensorInfo,
356 const std::string& descName,
357 const std::string& tensorName)
363 "not set on tensor {1}.", descName, tensorName));
367 void ValidatePerAxisQuantizationOffset(
const TensorInfo& tensorInfo,
368 const std::string& descName,
369 const std::string& tensorName)
372 if (quantizationOffset != 0)
375 "{0}: Quantization offset for per-axis quantization expected to be 0 on tensor {1}, but got: {2}",
376 descName, tensorName, quantizationOffset));
380 void ValidatePerAxisQuantization(
const TensorInfo& inputInfo,
384 const std::string& descName)
391 const bool canHavePerAxisQuantization = (
IsQuantized8BitType(inputDataType)) && inputDataType == outputDataType;
393 if (!canHavePerAxisQuantization)
396 "{0}: Per-axis quantization parameters set on tensor {1}, but data type does not support " 397 "per-axis quantization.", descName,
"weight"));
401 ValidPerAxisQuantizedDataType(weightInfo, descName,
"weight");
402 ValidatePerAxisQuantizationDimension(weightInfo, descName,
"weight");
403 ValidatePerAxisQuantizationOffset(weightInfo, descName,
"weight");
411 "{}: Per-axis quantization parameters not set on bias tensor, " 412 "despite being set on weight tensor.", descName));
415 ValidateTensorDataType(biasInfo, DataType::Signed32, descName,
"bias");
416 ValidatePerAxisQuantizationDimension(biasInfo, descName,
"bias");
417 ValidatePerAxisQuantizationOffset(biasInfo, descName,
"bias");
426 std::string
const& descName,
427 unsigned int numDimensions,
428 std::string
const& tensorName)
const 435 unsigned int squeezedDims = 0;
444 if (tensor.
GetNumDimensions() < numDimensions || squeezedDims > numDimensions)
448 tensorName +
" tensor.");
457 tensorName +
" tensor.");
464 unsigned int numDimension,
465 unsigned int numElements,
466 std::string
const& tensorName)
const 468 const std::string functionName{
"ValidateTensorNumDimNumElem"};
470 ValidateTensorNumElements(tensorInfo, functionName, numElements, tensorName);
475 unsigned int numExpectedIn,
unsigned int numExpectedOut)
const 477 ValidateTensors(
m_Inputs, numExpectedIn, descName,
"input");
478 ValidateTensors(
m_Outputs, numExpectedOut, descName,
"output");
484 const std::string descriptorName{
"MapQueueDescriptor"};
486 ValidateNumInputs(workloadInfo, descriptorName, 1);
487 ValidateNumOutputs(workloadInfo, descriptorName, 0);
489 for (
unsigned int i = 0; i <
m_Inputs.size(); ++i)
494 fmt::format(
"{}: Invalid NULL input {}.", descriptorName, static_cast<int>(i)));
502 const std::string descriptorName{
"UnmapQueueDescriptor"};
504 ValidateNumInputs(workloadInfo, descriptorName, 1);
505 ValidateNumOutputs(workloadInfo, descriptorName, 0);
507 for (
unsigned int i = 0; i <
m_Inputs.size(); ++i)
512 fmt::format(
"{}: Invalid NULL input {}.", descriptorName, static_cast<int>(i)));
520 const std::string descriptorName{
"MemCopyQueueDescriptor"};
522 ValidateNumInputs(workloadInfo, descriptorName, 1);
523 ValidateNumOutputs(workloadInfo, descriptorName , 1);
528 ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
529 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
534 "{0}: Number of inputs ({1}) does not match the number of outputs ({2}).",
538 for (
unsigned int i = 0; i <
m_Inputs.size(); ++i)
543 "{0}: Invalid NULL input {1}.", descriptorName, i));
556 ValidateNumInputs(workloadInfo,
"MemImportQueueDescriptor", 1);
557 ValidateNumOutputs(workloadInfo,
"MemImportQueueDescriptor" , 1);
569 "Number of input infos ({0}) does not match the number of output infos ({1})",
579 "Number of elements for tensor input and output {} does not match", i ));
591 "Number of inputs ({0}) does not match the number of outputs ({1})",
595 for (
unsigned int i = 0; i <
m_Inputs.size(); ++i)
612 ValidateNumInputs(workloadInfo,
"MemSyncQueueDescriptor", 1);
633 const std::string descriptorName{
"ActivationQueueDescriptor"};
635 ValidateNumInputs(workloadInfo, descriptorName, 1);
636 ValidateNumOutputs(workloadInfo, descriptorName, 1);
641 std::vector<DataType> supportedTypes =
651 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
652 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
653 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
658 const std::string descriptorName{
"ArgMinMaxQueueDescriptor"};
660 ValidateNumInputs(workloadInfo, descriptorName, 1);
661 ValidateNumOutputs(workloadInfo, descriptorName, 1);
672 std::vector<DataType> supportedInputTypes =
684 ValidateDataTypes(inputTensorInfo, supportedInputTypes, descriptorName);
686 auto inputShape = inputTensorInfo.
GetShape();
687 auto outputShape = outputTensorInfo.
GetShape();
692 const std::string outputShapeError{
": Output tensor shape does not match shape inferred from input tensor."};
695 if (inputShape.GetNumDimensions() == 1)
697 if (outputShape.GetNumDimensions() != 1 && outputShape[0] != 1)
704 for (
unsigned int i = 0; i < unsignedAxis; ++i)
706 if (outputShape[i] != inputShape[i])
712 for (
auto i = unsignedAxis + 1; i < inputNumDimensions; ++i)
714 if (outputShape[i - 1] != inputShape[i])
724 const std::string descriptorName{
"CastQueueDescriptor"};
726 ValidateNumInputs(workloadInfo, descriptorName, 1);
727 ValidateNumOutputs(workloadInfo, descriptorName, 1);
732 std::vector<DataType> supportedTypes =
745 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
746 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
751 const std::string descriptorName{
"SoftmaxQueueDescriptor"};
753 ValidateNumInputs(workloadInfo, descriptorName, 1);
754 ValidateNumOutputs(workloadInfo, descriptorName, 1);
759 std::vector<DataType> supportedTypes =
769 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
770 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
771 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
776 const std::string descriptorName{
"SplitterQueueDescriptor"};
778 ValidateNumInputs(workloadInfo, descriptorName, 1);
781 std::vector<DataType> supportedTypes =
797 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
799 const std::string outputName =
"output_" + std::to_string(i);
800 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input", outputName);
811 descriptorName +
": Number of split windows " 812 "has to match number of workloadInfo.m_OutputTensorInfos. " 813 "Number of windows: " +
814 to_string(m_ViewOrigins.size()) +
815 ". Number of workloadInfo.m_OutputTensorInfos: " + to_string(workloadInfo.
m_OutputTensorInfos.size()));
820 for(
unsigned int w = 0; w < m_ViewOrigins.size(); ++w )
827 "have the same dimensionality as the input tensor. " 828 "Window origin (index: " +
829 to_string(w) +
") has " + to_string(e.
m_Origin.size()) +
830 " dimensions, the input " 832 to_string(inputDims) +
" dimensions.");
834 for (
unsigned int i = 0; i < e.
m_Origin.size(); ++i)
840 "be smaller or equal than the size of the input in that coord.");
848 const std::string descriptorName{
"ConcatQueueDescriptor"};
850 ValidateNumOutputs(workloadInfo, descriptorName, 1);
870 if(m_Parameters.GetConcatAxis() > workloadInfo.
m_InputTensorInfos[0].GetShape().GetNumDimensions())
875 if (workloadInfo.
m_InputTensorInfos[0].GetShape().GetNumDimensions() - m_Parameters.GetConcatAxis() == 1)
883 descriptorName +
": Number of split windows " 884 "has to match number of workloadInfo.m_InputTensorInfos. " 885 "Number of windows: " +
886 to_string(m_ViewOrigins.size()) +
887 ". Number of workloadInfo.m_InputTensorInfos: " + to_string(workloadInfo.
m_InputTensorInfos.size()));
892 for(
unsigned int w = 0; w < m_ViewOrigins.size(); ++w )
896 if (e.
m_Origin.size() != outputDims)
899 "have the same dimensionality as the output tensor. " 900 "Window origin (index: " +
901 to_string(w) +
") has " + to_string(e.
m_Origin.size()) +
902 " dimensions, the output " 904 to_string(outputDims) +
" dimensions.");
907 for (
unsigned int i = 0; i < e.
m_Origin.size(); ++i)
913 "be smaller or equal than the size of the output in that coord.");
919 std::vector<DataType> supportedTypes =
935 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
937 const std::string inputName =
"input_" + std::to_string(i);
938 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, inputName,
"output");
944 const std::string descriptorName{
"StackQueueDescriptor"};
946 ValidateNumOutputs(workloadInfo, descriptorName, 1);
954 const TensorShape& inputShape = m_Parameters.m_InputShape;
973 "than the number of input dimensions.");
978 for (
unsigned int i = 0; i < m_Parameters.m_Axis; ++i)
980 if (outputShape[i] != inputShape[i])
983 "match shape inferred from input tensor.");
987 if (outputShape[m_Parameters.m_Axis] != m_Parameters.m_NumInputs)
990 "match shape inferred from input tensor.");
993 for (
unsigned int i = m_Parameters.m_Axis + 1; i < inputShape.
GetNumDimensions() + 1; ++i)
995 if (outputShape[i] != inputShape[i-1])
998 "match shape inferred from input tensor.");
1008 std::vector<DataType> supportedTypes =
1020 ValidateDataTypes(workloadInfo.
m_InputTensorInfos[0], supportedTypes, descriptorName);
1028 "input_" + std::to_string(i));
1040 const std::string descriptorName{
"FillQueueDescriptor"};
1042 ValidateNumInputs(workloadInfo, descriptorName, 1);
1043 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1050 std::vector<DataType> supportedTypes =
1058 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1063 const std::string descriptorName{
"FullyConnectedQueueDescriptor"};
1065 uint32_t numInputs = 2;
1066 if (m_Parameters.m_BiasEnabled)
1071 ValidateNumInputs(workloadInfo, descriptorName, numInputs);
1072 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1087 if (m_Parameters.m_BiasEnabled)
1091 ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
1097 std::vector<DataType> supportedTypes =
1107 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1115 "for BFloat16 input.");
1120 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1126 const std::string descriptorName{
"NormalizationQueueDescriptor"};
1128 ValidateNumInputs(workloadInfo, descriptorName, 1);
1129 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1135 std::vector<DataType> supportedTypes =
1145 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1147 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1149 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1154 const std::string descriptorName{
"AdditionQueueDescriptor"};
1156 ValidateNumInputs(workloadInfo, descriptorName, 2);
1157 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1163 std::vector<DataType> supportedTypes =
1174 ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
1175 ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
1176 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1178 ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName,
"input_0",
"input_1");
1179 ValidateTensorDataTypesMatch(inputTensorInfo1, outputTensorInfo, descriptorName,
"input_1",
"output");
1181 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
1191 const std::string descriptorName{
"MultiplicationQueueDescriptor"};
1193 ValidateNumInputs(workloadInfo, descriptorName, 2);
1194 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1200 std::vector<DataType> supportedTypes =
1211 ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
1212 ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
1213 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1215 ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName,
"input_0",
"input_1");
1216 ValidateTensorDataTypesMatch(inputTensorInfo1, outputTensorInfo, descriptorName,
"input_1",
"output");
1218 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
1228 const std::string descriptorName{
"BatchNormalizationQueueDescriptor"};
1230 ValidateNumInputs(workloadInfo, descriptorName, 1);
1231 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1236 std::vector<DataType> supportedTypes =
1246 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1247 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1249 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1250 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1252 ValidatePointer(m_Mean, descriptorName,
"mean");
1253 ValidatePointer(m_Variance, descriptorName,
"variance");
1254 ValidatePointer(m_Beta, descriptorName,
"beta");
1255 ValidatePointer(m_Gamma, descriptorName,
"gamma");
1257 const TensorInfo& mean = m_Mean->GetTensorInfo();
1258 const TensorInfo& variance = m_Variance->GetTensorInfo();
1259 const TensorInfo& beta = m_Beta->GetTensorInfo();
1260 const TensorInfo& gamma = m_Gamma->GetTensorInfo();
1267 ValidateTensorShapesMatch(mean, variance, descriptorName,
"mean",
"variance");
1268 ValidateTensorShapesMatch(mean, beta, descriptorName,
"mean",
"beta");
1269 ValidateTensorShapesMatch(mean, gamma, descriptorName,
"mean",
"gamma");
1274 const std::string descriptorName{
"Convolution2dQueueDescriptor"};
1276 uint32_t numInputs = 2;
1277 if (m_Parameters.m_BiasEnabled)
1282 ValidateNumInputs(workloadInfo, descriptorName, numInputs);
1283 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1295 ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);
1298 if (m_Parameters.m_BiasEnabled)
1300 optionalBiasTensorInfo = MakeOptional<TensorInfo>(workloadInfo.
m_InputTensorInfos[2]);
1304 ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
1307 if (m_Parameters.m_StrideX <= 0 || m_Parameters.m_StrideY <= 0 )
1310 fmt::format(
"{}: strideX (provided {}) and strideY (provided {}) " 1311 "cannot be either negative or 0.",
1312 descriptorName, m_Parameters.m_StrideX, m_Parameters.m_StrideY));
1315 ValidatePerAxisQuantization(inputTensorInfo,
1318 optionalBiasTensorInfo,
1321 std::vector<DataType> supportedTypes =
1332 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1340 "for BFloat16 input.");
1345 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1351 const std::string descriptorName{
"Convolution3dQueueDescriptor"};
1353 uint32_t numInputs = 2;
1354 if (m_Parameters.m_BiasEnabled)
1358 ValidateNumInputs(workloadInfo, descriptorName, numInputs);
1359 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1370 ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);
1373 if (m_Parameters.m_BiasEnabled)
1375 optionalBiasTensorInfo = MakeOptional<TensorInfo>(workloadInfo.
m_InputTensorInfos[2]);
1379 ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
1382 if (m_Parameters.m_StrideX <= 0 || m_Parameters.m_StrideY <= 0 || m_Parameters.m_StrideZ <= 0 )
1385 fmt::format(
"{}: strideX (provided {}), strideY (provided {}) or strideZ (provided {})" 1386 "cannot be either negative or 0.",
1387 descriptorName, m_Parameters.m_StrideX, m_Parameters.m_StrideY, m_Parameters.m_StrideZ));
1390 ValidatePerAxisQuantization(inputTensorInfo,
1393 optionalBiasTensorInfo,
1396 std::vector<DataType> supportedTypes =
1407 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1408 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1413 const std::string descriptorName{
"DepthwiseConvolution2dQueueDescriptor"};
1415 uint32_t numInputs = 2;
1416 if (m_Parameters.m_BiasEnabled)
1421 ValidateNumInputs(workloadInfo, descriptorName, numInputs);
1422 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1433 if (m_Parameters.m_DilationX < 1 || m_Parameters.m_DilationY < 1 )
1436 fmt::format(
"{}: dilationX (provided {}) and dilationY (provided {}) " 1437 "cannot be smaller than 1.",
1438 descriptorName, m_Parameters.m_DilationX, m_Parameters.m_DilationX));
1441 if (m_Parameters.m_StrideX <= 0 || m_Parameters.m_StrideY <= 0 )
1444 fmt::format(
"{}: strideX (provided {}) and strideY (provided {}) " 1445 "cannot be either negative or 0.",
1446 descriptorName, m_Parameters.m_StrideX, m_Parameters.m_StrideY));
1449 if (weightTensorInfo.
GetShape()[0] != 1)
1452 "{0}: The weight format in armnn is expected to be [1, H, W, Cout]." 1453 "But first dimension is not equal to 1. Provided weight shape: [{1}, {2}, {3}, {4}]",
1461 const unsigned int channelIndex = (m_Parameters.m_DataLayout ==
DataLayout::NCHW) ? 1 : 3;
1462 const unsigned int numWeightOutputChannelsRefFormat = weightTensorInfo.
GetShape()[3];
1463 const unsigned int numWeightOutputChannelsAclFormat = weightTensorInfo.
GetShape()[1];
1464 const unsigned int numOutputChannels = outputTensorInfo.
GetShape()[channelIndex];
1467 bool validRefFormat = (numWeightOutputChannelsRefFormat == numOutputChannels);
1468 bool validAclFormat = (numWeightOutputChannelsAclFormat == numOutputChannels);
1470 if (!(validRefFormat || validAclFormat))
1473 "{0}: The weight format in armnn is expected to be [1, H, W, Cout] (CpuRef) or [1, Cout, H, W] " 1474 "(CpuAcc/GpuAcc). But neither the 4th (CpuRef) or 2nd (CpuAcc/GpuAcc) dimension is equal to Cout." 1475 "Cout = {1} Provided weight shape: [{2}, {3}, {4}, {5}]",
1484 ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);
1487 if (m_Parameters.m_BiasEnabled)
1489 optionalBiasTensorInfo = MakeOptional<TensorInfo>(workloadInfo.
m_InputTensorInfos[2]);
1492 ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
1495 ValidatePerAxisQuantization(inputTensorInfo,
1498 optionalBiasTensorInfo,
1501 std::vector<DataType> supportedTypes =
1511 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1512 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1517 const std::string descriptorName{
"PermuteQueueDescriptor"};
1519 ValidateNumInputs(workloadInfo, descriptorName, 1);
1520 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1530 for (
unsigned int i = 0u; i < mapping.
GetSize(); ++i)
1532 if (inputTensorInfo.
GetShape()[i] != outputTensorInfo.
GetShape()[mapping[i]])
1535 " (=" + to_string(inputTensorInfo.
GetShape()[i]) +
") " +
1536 "must match dst dimension " + to_string(mapping[i]) +
1537 " (=" + to_string(outputTensorInfo.
GetShape()[mapping[i]]) +
")");
1541 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1546 const std::string descriptorName{
"Pooling2dQueueDescriptor"};
1548 ValidateNumInputs(workloadInfo, descriptorName, 1);
1549 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1557 std::vector<DataType> supportedTypes =
1567 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1568 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1573 const std::string descriptorName{
"Pooling3dQueueDescriptor"};
1575 ValidateNumInputs(workloadInfo, descriptorName, 1);
1576 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1584 std::vector<DataType> supportedTypes =
1594 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1595 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1599 void ResizeBilinearQueueDescriptor::Validate(
const WorkloadInfo& workloadInfo)
const 1601 const std::string descriptorName{
"ResizeBilinearQueueDescriptor"};
1603 ValidateNumInputs(workloadInfo, descriptorName, 1);
1604 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1612 std::vector<DataType> supportedTypes =
1622 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1623 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1626 const unsigned int inputBatchSize = inputTensorInfo.
GetShape()[0];
1627 const unsigned int outputBatchSize = outputTensorInfo.
GetShape()[0];
1628 if (inputBatchSize != outputBatchSize)
1631 fmt::format(
"{}: Input batch size ({}) does not match output batch size ({})",
1632 descriptorName, inputBatchSize, outputBatchSize));
1638 if (inputChannelCount != outputChannelCount)
1641 fmt::format(
"{}: Input channel count ({}) does not match output channel count ({})",
1642 descriptorName, inputChannelCount, outputChannelCount));
1648 const std::string descriptorName{
"ResizeQueueDescriptor"};
1650 ValidateNumInputs(workloadInfo, descriptorName, 1);
1651 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1659 std::vector<DataType> supportedTypes =
1669 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1670 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1673 const unsigned int inputBatchSize = inputTensorInfo.
GetShape()[0];
1674 const unsigned int outputBatchSize = outputTensorInfo.
GetShape()[0];
1675 if (inputBatchSize != outputBatchSize)
1678 fmt::format(
"{}: Input batch size ({}) does not match output batch size ({})",
1679 descriptorName, inputBatchSize, outputBatchSize));
1685 if (inputChannelCount != outputChannelCount)
1688 fmt::format(
"{}: Input channel count ({}) does not match output channel count ({})",
1689 descriptorName, inputChannelCount, outputChannelCount));
1695 const std::string descriptorName{
"FakeQuantizationQueueDescriptor"};
1697 ValidateNumInputs(workloadInfo, descriptorName, 1);
1698 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1706 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1708 if (m_Parameters.m_Min > m_Parameters.m_Max)
1716 const std::string descriptorName{
"InstanceNormalizationQueueDescriptor"};
1718 ValidateNumInputs(workloadInfo, descriptorName, 1);
1719 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1729 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1732 std::vector<DataType> supportedTypes =
1739 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1740 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1745 const std::string descriptorName{
"L2NormalizationQueueDescriptor"};
1747 ValidateNumInputs(workloadInfo, descriptorName, 1);
1748 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1758 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1761 std::vector<DataType> supportedTypes =
1771 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1772 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1777 const std::string descriptorName{
"LogSoftmaxQueueDescriptor"};
1779 ValidateNumInputs(workloadInfo, descriptorName, 1);
1780 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1785 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1787 std::vector<DataType> supportedTypes =
1794 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1795 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1800 const std::string descriptorName{
"ConstantQueueDescriptor"};
1802 ValidateNumInputs(workloadInfo, descriptorName, 0);
1803 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1811 ValidateTensorShapesMatch(m_LayerOutput->GetTensorInfo(), outputTensorInfo, descriptorName,
"constant",
"output");
1814 std::vector<DataType> supportedTypes =
1826 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1831 const std::string descriptorName{
"ReshapeQueueDescriptor"};
1833 ValidateNumInputs(workloadInfo, descriptorName, 1);
1834 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1839 ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1842 std::vector<DataType> supportedTypes =
1854 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1855 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1860 const std::string descriptorName{
"SpaceToBatchNdQueueDescriptor"};
1862 ValidateNumInputs(workloadInfo, descriptorName, 1);
1863 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1871 if (m_Parameters.m_BlockShape.size() != 2)
1876 if (m_Parameters.m_BlockShape.size() != m_Parameters.m_PadList.size())
1879 "dimensions as Block Shape.");
1884 std::pair<unsigned int, unsigned int> heightPad = m_Parameters.m_PadList[0];
1885 std::pair<unsigned int, unsigned int> widthPad = m_Parameters.m_PadList[1];
1889 const unsigned int inputWidth = inputShape[dimensionIndices.
GetWidthIndex()] +
1890 widthPad.first + widthPad.second;
1891 const unsigned int inputHeight = inputShape[dimensionIndices.
GetHeightIndex()] +
1892 heightPad.first + heightPad.second;
1894 const unsigned int numInputElements = inputShape[0] * inputHeight * inputWidth *
1896 const unsigned int numOutputElements = outputTensorInfo.
GetNumElements();
1898 if (numOutputElements != numInputElements)
1901 to_string(numInputElements) +
" after padding but output tensor has " +
1902 to_string(numOutputElements) +
" elements.");
1905 if (inputHeight % m_Parameters.m_BlockShape[0] != 0 || inputWidth % m_Parameters.m_BlockShape[1] != 0)
1908 "divisible by Block Shape in all spatial dimensions");
1911 std::vector<DataType> supportedTypes =
1921 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1922 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1927 const std::string descriptorName{
"SpaceToDepthQueueDescriptor"};
1929 ValidateNumInputs(workloadInfo, descriptorName, 1);
1930 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1938 std::vector<DataType> supportedTypes =
1948 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1949 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1951 ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1953 if (m_Parameters.m_BlockSize == 0)
1959 const unsigned int wIndex = dimensionIndices.
GetWidthIndex();
1964 if (inputShape[hIndex] % m_Parameters.m_BlockSize != 0 || inputShape[wIndex] % m_Parameters.m_BlockSize != 0)
1967 "by block size in all spatial dimensions");
1971 if (outputShape[cIndex] % (m_Parameters.m_BlockSize * m_Parameters.m_BlockSize) != 0)
1974 "must be divisible by the square of block size." );
1980 const std::string descriptorName{
"FloorQueueDescriptor"};
1982 ValidateNumInputs(workloadInfo, descriptorName, 1);
1983 ValidateNumOutputs(workloadInfo, descriptorName, 1);
1988 std::vector<DataType> supportedTypes =
1996 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1997 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1998 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
1999 ValidateTensorQuantizationSpace(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2006 const std::string descriptorName{
"LstmQueueDescriptor"};
2018 std::vector<DataType> supportedTypes =
2027 ValidateDataTypes(workloadInfo.
m_InputTensorInfos[0], supportedTypes, descriptorName);
2036 "input_" + std::to_string(i));
2043 "LstmQueueDescriptor",
2045 "output_" + std::to_string(i));
2051 if (m_Parameters.m_ClippingThresCell < 0.0f)
2055 if (m_Parameters.m_ClippingThresProj < 0.0f)
2063 ValidatePointer(m_InputToOutputWeights,
"Null pointer check",
"InputToOutputWeights");
2064 const uint32_t n_cell = m_InputToOutputWeights->GetShape()[0];
2065 ValidatePointer(m_RecurrentToOutputWeights,
"Null pointer check",
"RecurrentToOutputWeights");
2066 const uint32_t n_output = m_RecurrentToOutputWeights->GetShape()[1];
2070 descriptorName +
" input_0");
2073 descriptorName +
" input_1");
2076 descriptorName +
" input_2");
2078 unsigned int scratchBufferSize = m_Parameters.m_CifgEnabled ? n_cell * 3 : n_cell * 4;
2080 descriptorName +
" output_0");
2083 descriptorName +
" output_1");
2086 descriptorName +
" output_2");
2089 descriptorName +
" output_3");
2092 if ( m_InputToInputWeights )
2095 (n_cell * n_input),
"InputLayerNormWeights");
2098 ValidatePointer(m_InputToForgetWeights,
"Null pointer check",
"InputToForgetWeights");
2100 (n_cell * n_input),
"InputToForgetWeights");
2102 ValidatePointer(m_InputToCellWeights,
"Null pointer check",
"InputToCellWeights");
2104 (n_cell * n_input),
"InputToCellWeights");
2106 if ( m_RecurrentToInputWeights )
2109 (n_cell * n_output),
"RecurrentToInputWeights");
2112 ValidatePointer(m_RecurrentToForgetWeights,
"Null pointer check",
"RecurrentToForgetWeights");
2114 (n_cell * n_output),
"RecurrentToForgetWeights");
2116 ValidatePointer(m_RecurrentToCellWeights,
"Null pointer check",
"RecurrentToCellWeights");
2118 (n_cell * n_output),
"RecurrentToCellWeights");
2122 bool cifg_weights_all_or_none = ((m_InputToInputWeights && m_RecurrentToInputWeights &&
2123 !m_Parameters.m_CifgEnabled) ||
2124 (!m_InputToInputWeights && !m_RecurrentToInputWeights &&
2125 m_Parameters.m_CifgEnabled));
2126 if (!cifg_weights_all_or_none)
2129 "RecurrentToInputWeights must either both be present (regular LSTM) " 2130 "or both not present (CIFG-LSTM). In addition CifgEnable must be set " 2134 if ( m_CellToInputWeights )
2137 n_cell,
"CellToInputWeights");
2139 if ( m_CellToForgetWeights )
2142 n_cell,
"CellToForgetWeights");
2144 if ( m_CellToOutputWeights )
2147 n_cell,
"CellToOutputWeights");
2151 bool peephole_weights_all_or_none =
2152 (((m_CellToInputWeights || m_Parameters.m_CifgEnabled) && m_CellToForgetWeights
2153 && m_CellToOutputWeights && m_Parameters.m_PeepholeEnabled)
2154 || ( !m_CellToInputWeights && !m_CellToForgetWeights
2155 && !m_CellToOutputWeights && !m_Parameters.m_PeepholeEnabled));
2156 if (!peephole_weights_all_or_none)
2162 if (m_Parameters.m_CifgEnabled)
2164 if (m_InputGateBias)
2171 if (!m_InputGateBias)
2174 "must be present.");
2177 n_cell,
"InputGateBias");
2180 ValidatePointer(m_ForgetGateBias,
"Null pointer check",
"ForgetGateBias");
2183 ValidatePointer(m_CellBias,
"Null pointer check",
"CellBias");
2186 ValidatePointer(m_OutputGateBias,
"Null pointer check",
"OutputGateBias");
2189 if (m_ProjectionWeights)
2192 (n_cell * n_output),
"ProjectionWeights");
2194 if (m_ProjectionBias)
2203 bool projecton_tensors_consistent = ((!m_ProjectionWeights && !m_ProjectionBias &&
2204 !m_Parameters.m_ProjectionEnabled)
2205 || (m_ProjectionWeights && !m_ProjectionBias &&
2206 m_Parameters.m_ProjectionEnabled)
2207 || (m_ProjectionWeights && m_ProjectionBias &&
2208 m_Parameters.m_ProjectionEnabled));
2209 if (!projecton_tensors_consistent)
2218 if (m_InputLayerNormWeights)
2222 if (m_ForgetLayerNormWeights)
2226 if (m_CellLayerNormWeights)
2230 if (m_OutputLayerNormWeights)
2235 if (m_Parameters.m_LayerNormEnabled)
2237 if (!m_Parameters.m_CifgEnabled)
2239 if (!m_InputLayerNormWeights)
2242 "disabled but InputLayerNormWeights are not present");
2245 1, n_cell,
"InputLayerNormWeights");
2247 else if (m_InputLayerNormWeights)
2253 ValidatePointer(m_ForgetLayerNormWeights,
"Null pointer check layer normalisation enabled",
2254 "ForgetLayerNormWeights");
2257 ValidatePointer(m_OutputLayerNormWeights,
"Null pointer check layer normalisation enabled",
2258 "OutputLayerNormWeights");
2261 ValidatePointer(m_CellLayerNormWeights,
"Null pointer check layer normalisation enabled",
2262 "CellLayerNormWeights");
2265 else if (m_InputLayerNormWeights || m_ForgetLayerNormWeights || m_OutputLayerNormWeights || m_CellLayerNormWeights)
2268 "normalisation weights are present.");
2274 const std::string descriptorName{
"ConvertBf16ToFp32QueueDescriptor"};
2276 ValidateNumInputs(workloadInfo, descriptorName, 1);
2277 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2292 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2297 const std::string descriptorName{
"ConvertFp32ToBf16QueueDescriptor"};
2299 ValidateNumInputs(workloadInfo, descriptorName, 1);
2300 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2315 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2320 const std::string descriptorName{
"ConvertFp32ToFp16QueueDescriptor"};
2322 ValidateNumInputs(workloadInfo, descriptorName, 1);
2323 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2338 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2343 const std::string descriptorName{
"ConvertFp16ToFp32QueueDescriptor"};
2345 ValidateNumInputs(workloadInfo, descriptorName, 1);
2346 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2361 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2366 const std::string descriptorName{
"DivisionQueueDescriptor"};
2368 ValidateNumInputs(workloadInfo, descriptorName, 2);
2369 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2375 std::vector<DataType> supportedTypes =
2386 ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2387 ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2388 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
2390 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2400 const std::string descriptorName{
"SubtractionQueueDescriptor"};
2402 ValidateNumInputs(workloadInfo, descriptorName, 2);
2403 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2409 std::vector<DataType> supportedTypes =
2420 ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2421 ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2422 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
2424 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2434 const std::string descriptorName{
"MaximumQueueDescriptor"};
2436 ValidateNumInputs(workloadInfo, descriptorName, 2);
2437 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2443 std::vector<DataType> supportedTypes =
2454 ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2455 ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2456 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
2458 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2468 const std::string descriptorName{
"MeanQueueDescriptor"};
2470 ValidateNumInputs(workloadInfo, descriptorName, 1);
2471 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2476 std::vector<DataType> supportedTypes =
2488 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2489 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2491 if (m_Parameters.m_KeepDims)
2495 else if (m_Parameters.m_Axis.empty())
2501 unsigned int outputDim =
2505 outputDim > 0 ? outputDim : 1,
2512 const std::string descriptorName{
"PadQueueDescriptor"};
2514 ValidateNumInputs(workloadInfo, descriptorName, 1);
2515 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2526 "as there are dimensions in the input tensor that is " +
2528 " not " + std::to_string(m_Parameters.m_PadList.size()) +
" entries.");
2534 const std::string descriptorName{
"QuantizeQueueDescriptor"};
2536 ValidateNumInputs(workloadInfo, descriptorName, 1);
2537 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2542 std::vector<DataType> supportedTypes =
2553 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2563 const std::string descriptorName{
"BatchToSpaceNdQueueDescriptor"};
2565 ValidateNumInputs(workloadInfo, descriptorName, 1);
2566 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2571 std::vector<DataType> supportedTypes =
2581 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2582 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2587 const std::string descriptorName{
"StridedSliceQueueDescriptor"};
2589 ValidateNumInputs(workloadInfo, descriptorName, 1);
2590 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2595 std::vector<DataType> supportedTypes =
2605 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2606 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2608 ValidateTensorQuantizationSpace(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2617 if (m_Parameters.m_Begin.size() != rank)
2622 if (m_Parameters.m_End.size() != rank)
2627 if (m_Parameters.m_Stride.size() != rank)
2633 for (
auto& stride : m_Parameters.m_Stride)
2644 const std::string descriptorName{
"MinimumQueueDescriptor"};
2646 ValidateNumInputs(workloadInfo, descriptorName, 2);
2647 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2653 std::vector<DataType> supportedTypes =
2664 ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2665 ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2666 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
2668 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2678 const std::string descriptorName{
"DebugQueueDescriptor"};
2680 ValidateNumInputs(workloadInfo, descriptorName, 1);
2681 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2686 const std::string descriptorName{
"EqualQueueDescriptor"};
2688 ValidateNumInputs(workloadInfo, descriptorName, 2);
2689 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2695 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2710 const std::string descriptorName{
"GreaterQueueDescriptor"};
2712 ValidateNumInputs(workloadInfo, descriptorName, 2);
2713 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2719 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2734 const std::string descriptorName{
"RsqrtQueueDescriptor"};
2736 ValidateNumInputs(workloadInfo, descriptorName, 1);
2737 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2742 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2744 std::vector<DataType> supportedTypes =
2754 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2755 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2760 const std::string descriptorName{
"GatherNdQueueDescriptor"};
2762 ValidateNumInputs(workloadInfo, descriptorName, 2);
2763 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2774 std::vector<DataType> supportedTypes =
2785 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2787 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2795 const std::string descriptorName{
"GatherQueueDescriptor"};
2797 ValidateNumInputs(workloadInfo, descriptorName, 2);
2798 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2809 std::vector<DataType> supportedTypes =
2820 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2822 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
2830 const std::string& descriptorName{
"DetectionPostProcessQueueDescriptor"};
2832 ValidateNumInputs(workloadInfo, descriptorName, 2);
2840 if (m_Anchors ==
nullptr)
2847 const TensorInfo& anchorsInfo = m_Anchors->GetTensorInfo();
2858 const std::vector<DataType> supportedInputTypes =
2868 ValidateDataTypes(boxEncodingsInfo, supportedInputTypes, descriptorName);
2869 ValidateDataTypes(scoresInfo, supportedInputTypes, descriptorName);
2870 ValidateDataTypes(anchorsInfo, supportedInputTypes, descriptorName);
2878 ValidateTensorDataType(detectionBoxesInfo,
DataType::Float32, descriptorName,
"detection boxes");
2879 ValidateTensorDataType(detectionScoresInfo,
DataType::Float32, descriptorName,
"detection scores");
2880 ValidateTensorDataType(detectionClassesInfo,
DataType::Float32, descriptorName,
"detection classes");
2881 ValidateTensorDataType(numDetectionsInfo,
DataType::Float32, descriptorName,
"num detections");
2883 if (m_Parameters.m_NmsIouThreshold <= 0.0f || m_Parameters.m_NmsIouThreshold > 1.0f)
2886 "must be positive and less than or equal to 1.");
2889 if (scoresInfo.
GetShape()[2] != m_Parameters.m_NumClasses + 1)
2892 "should be equal to number of classes + 1.");
2898 const std::string& descriptorName{
"DequantizeQueueDescriptor"};
2900 ValidateNumInputs(workloadInfo, descriptorName, 1);
2901 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2906 std::vector<DataType> inputSupportedTypes =
2914 ValidateDataTypes(inputTensorInfo, inputSupportedTypes, descriptorName);
2916 std::vector<DataType> outputSupportedTypes =
2923 ValidateDataTypes(outputTensorInfo, outputSupportedTypes, descriptorName);
2928 const std::string& descriptorName{
"MergeQueueDescriptor"};
2930 ValidateNumInputs(workloadInfo, descriptorName, 2);
2931 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2937 ValidateTensorShapesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName,
"input_0",
"input_1");
2938 ValidateTensorShapesMatch(inputTensorInfo0, outputTensorInfo, descriptorName,
"input_0",
"output");
2940 ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName,
"input_0",
"input_1");
2941 ValidateTensorDataTypesMatch(inputTensorInfo0, outputTensorInfo, descriptorName,
"input_0",
"output");
2946 const std::string& descriptorName{
"ShapeQueueDescriptor"};
2948 ValidateNumInputs(workloadInfo, descriptorName, 1);
2949 ValidateNumOutputs(workloadInfo, descriptorName, 1);
2954 std::vector<DataType> supportedTypes =
2967 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2968 ValidateDataTypes(outputTensorInfo, {DataType::Signed32}, descriptorName);
2973 const std::string& descriptorName{
"SwitchQueueDescriptor"};
2975 ValidateNumInputs(workloadInfo, descriptorName, 2);
2976 ValidateNumOutputs(workloadInfo, descriptorName, 2);
2984 std::vector<DataType> supportedTypes =
2993 ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2994 ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2996 ValidateDataTypes(outputTensorInfo0, supportedTypes, descriptorName);
2997 ValidateDataTypes(outputTensorInfo1, supportedTypes, descriptorName);
2999 ValidateTensorShapesMatch(inputTensorInfo0,
3005 ValidateTensorShapesMatch(inputTensorInfo0,
3019 const std::string& descriptorName{
"PreluQueueDescriptor"};
3021 ValidateNumInputs(workloadInfo, descriptorName, 2);
3022 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3028 std::vector<DataType> supportedTypes
3038 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3039 ValidateDataTypes(alphaTensorInfo, supportedTypes, descriptorName);
3041 ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
3043 ValidateTensorDataTypesMatch(inputTensorInfo, alphaTensorInfo, descriptorName,
"input",
"alpha");
3044 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"ouptut");
3046 ValidateBroadcastTensorShapesMatch(inputTensorInfo,
3056 const std::string descriptorName{
"TransposeConvolution2dQueueDescriptor"};
3058 ValidateNumInputs(workloadInfo, descriptorName, 1);
3059 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3067 ValidatePointer(m_Weight, descriptorName,
"weight");
3069 const TensorInfo& weightTensorInfo = m_Weight->GetTensorInfo();
3072 ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);
3075 if (m_Parameters.m_BiasEnabled)
3077 ValidatePointer(m_Bias, descriptorName,
"bias");
3079 optionalBiasTensorInfo = MakeOptional<TensorInfo>(m_Bias->GetTensorInfo());
3083 ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
3086 ValidatePerAxisQuantization(inputTensorInfo,
3089 optionalBiasTensorInfo,
3092 std::vector<DataType> supportedTypes =
3102 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3103 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3108 const std::string descriptorName{
"TransposeQueueDescriptor"};
3110 ValidateNumInputs(workloadInfo, descriptorName, 1);
3111 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3121 for (
unsigned int i = 0u; i < mapping.
GetSize(); ++i)
3123 if (inputTensorInfo.
GetShape()[mapping[i]] != outputTensorInfo.
GetShape()[i])
3126 " (=" + to_string(inputTensorInfo.
GetShape()[mapping[i]]) +
") " +
3127 "must match dst dimension " + to_string(i) +
3128 " (=" + to_string(outputTensorInfo.
GetShape()[i]) +
")");
3132 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3137 const std::string descriptorName{
"TransposeQueueDescriptor"};
3139 ValidateNumInputs(workloadInfo, descriptorName, 1);
3140 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3145 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3150 const std::string descriptorName{
"QLstmQueueDescriptor"};
3153 ValidateNumInputs(workloadInfo, descriptorName, 3);
3154 ValidateNumOutputs(workloadInfo, descriptorName, 3);
3166 std::vector<DataType> inputOutputSupportedTypes =
3171 std::vector<DataType> cellStateSupportedTypes =
3176 std::vector<DataType> weightsSupportedTypes =
3181 std::vector<DataType> layerNormPeepholeWeightsSupportedTypes =
3186 std::vector<DataType> biasSupportedTypes =
3192 ValidateDataTypes(inputInfo, inputOutputSupportedTypes, descriptorName);
3193 ValidateDataTypes(outputStateInInfo, inputOutputSupportedTypes, descriptorName);
3194 ValidateDataTypes(cellStateInInfo, cellStateSupportedTypes, descriptorName);
3196 ValidateDataTypes(outputStateOutInfo, inputOutputSupportedTypes, descriptorName);
3197 ValidateDataTypes(cellStateOutInfo, cellStateSupportedTypes, descriptorName);
3198 ValidateDataTypes(outputInfo, inputOutputSupportedTypes, descriptorName);
3201 ValidateTensorDataTypesMatch(inputInfo, outputStateInInfo, descriptorName,
"input",
"outputStateIn");
3202 ValidateTensorDataTypesMatch(outputStateInInfo, outputStateOutInfo, descriptorName,
3203 "outputStateIn",
"outputStateOut");
3204 ValidateTensorDataTypesMatch(cellStateInInfo, cellStateOutInfo, descriptorName,
"cellStateIn",
"cellStateOut");
3207 const uint32_t numBatches = inputInfo.GetShape()[0];
3208 const uint32_t inputSize = inputInfo.GetShape()[1];
3209 const uint32_t outputSize = outputStateInInfo.GetShape()[1];
3210 const uint32_t numUnits = cellStateInInfo.GetShape()[1];
3222 ValidatePointer(m_InputToForgetWeights, descriptorName,
"InputToForgetWeights");
3223 auto inputToForgetWeightsInfo = m_InputToForgetWeights->GetTensorInfo();
3226 ValidatePointer(m_InputToCellWeights, descriptorName,
"InputToCellWeights");
3227 auto inputToCellWeightsInfo = m_InputToCellWeights->GetTensorInfo();
3230 ValidatePointer(m_InputToOutputWeights, descriptorName,
"InputToOutputWeights");
3231 auto inputToOutputWeightsInfo = m_InputToOutputWeights->GetTensorInfo();
3234 ValidatePointer(m_RecurrentToForgetWeights, descriptorName,
"RecurrentToForgetWeights");
3235 auto recurrentToForgetWeightsInfo = m_RecurrentToForgetWeights->GetTensorInfo();
3237 " RecurrentToForgetWeights");
3239 ValidatePointer(m_RecurrentToCellWeights, descriptorName,
"RecurrentToCellWeights");
3240 auto recurrentToCellWeightsInfo = m_RecurrentToCellWeights->GetTensorInfo();
3243 ValidatePointer(m_RecurrentToOutputWeights, descriptorName,
"RecurrentToOutputWeights");
3244 auto recurrentToOutputWeightsInfo = m_RecurrentToOutputWeights->GetTensorInfo();
3248 ValidateDataTypes(inputToForgetWeightsInfo, weightsSupportedTypes, descriptorName);
3250 ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToCellWeightsInfo, descriptorName,
3251 "inputToForgetWeights",
"inputToCellWeights");
3252 ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToOutputWeightsInfo, descriptorName,
3253 "inputToForgetWeights",
"inputToOutputWeights");
3255 ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToForgetWeightsInfo, descriptorName,
3256 "inputToForgetWeights",
"recurrentToForgeteights");
3257 ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToCellWeightsInfo, descriptorName,
3258 "inputToForgetWeights",
"recurrentToCellWeights");
3259 ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToOutputWeightsInfo, descriptorName,
3260 "inputToForgetWeights",
"recurrentToOutputWeights");
3263 ValidatePointer(m_ForgetGateBias, descriptorName,
"ForgetGateBias");
3264 auto forgetGateBiasInfo = m_ForgetGateBias->GetTensorInfo();
3267 ValidatePointer(m_CellBias, descriptorName,
"CellBias");
3268 auto cellBiasInfo = m_CellBias->GetTensorInfo();
3271 ValidatePointer(m_OutputGateBias, descriptorName,
"OutputGateBias");
3272 auto outputGateBiasInfo = m_OutputGateBias->GetTensorInfo();
3276 ValidateDataTypes(forgetGateBiasInfo, biasSupportedTypes, descriptorName);
3278 ValidateTensorDataTypesMatch(forgetGateBiasInfo, cellBiasInfo, descriptorName,
3279 "forgetGateBias",
"cellBias");
3280 ValidateTensorDataTypesMatch(forgetGateBiasInfo, outputGateBiasInfo, descriptorName,
3281 "forgetGateBias",
"outputGateBias");
3284 const bool allCifgParamsPresentOrNot = ((m_InputToInputWeights && m_RecurrentToInputWeights && m_InputGateBias &&
3285 !m_Parameters.m_CifgEnabled) ||
3286 (!m_InputToInputWeights && !m_RecurrentToInputWeights &&
3287 !m_InputGateBias && m_Parameters.m_CifgEnabled));
3289 if (!allCifgParamsPresentOrNot)
3292 ": InputToInputWeights, RecurrentToInputWeights and InputGateBias must either all be present " 3293 "(CIFG disabled) or not be present at all (CIFG enabled). m_Parameters.m_CifgEnabled should be " 3294 "set appropriately.");
3297 if (!m_Parameters.m_CifgEnabled)
3300 auto inputToInputWeightsInfo = m_InputToInputWeights->GetTensorInfo();
3303 auto recurrentToInputWeightsInfo = m_RecurrentToInputWeights->GetTensorInfo();
3305 " RecurrentToInputWeights");
3307 auto inputGateBiasInfo = m_InputGateBias->GetTensorInfo();
3311 ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToInputWeightsInfo, descriptorName,
3312 "inputToForgetWeights",
"inputToInputWeights");
3313 ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToInputWeightsInfo, descriptorName,
3314 "inputToForgetWeights",
"recurrentToInputWeights");
3315 ValidateTensorDataTypesMatch(forgetGateBiasInfo, inputGateBiasInfo, descriptorName,
3316 "forgetGateBias",
"inputGateBias");
3320 bool allPeepholeWeightsPresentOrNot =
3321 (((m_CellToInputWeights || m_Parameters.m_CifgEnabled) && m_CellToForgetWeights
3322 && m_CellToOutputWeights && m_Parameters.m_PeepholeEnabled)
3323 || (!m_CellToInputWeights && !m_CellToForgetWeights
3324 && !m_CellToOutputWeights && !m_Parameters.m_PeepholeEnabled));
3326 if (!allPeepholeWeightsPresentOrNot)
3329 ": CellToInputWeights, CellToForgetWeights and CellToOutputWeights should all be present (Peephole " 3330 "enabled) or not be present at all (Peephole disabled). CellToInputWeights should only be present " 3331 "when Peephole is enabled and CIFG is disabled. m_Parameters.m_PeepholeEnabled should be set " 3335 if (m_Parameters.m_PeepholeEnabled)
3337 auto cellToForgetWeightsInfo = m_CellToForgetWeights->GetTensorInfo();
3339 ValidateDataTypes(cellToForgetWeightsInfo, layerNormPeepholeWeightsSupportedTypes, descriptorName);
3341 auto cellToOutputWeightsInfo = m_CellToOutputWeights->GetTensorInfo();
3343 ValidateTensorDataTypesMatch(cellToForgetWeightsInfo, cellToOutputWeightsInfo, descriptorName,
3344 "cellToForgetWeight",
"cellToOutputWeights");
3346 if (!m_Parameters.m_CifgEnabled)
3348 auto cellToInputWeightsInfo = m_CellToInputWeights->GetTensorInfo();
3350 ValidateTensorDataTypesMatch(cellToForgetWeightsInfo, cellToInputWeightsInfo, descriptorName,
3351 "cellToForgetWeights",
"cellToInputWeights");
3356 bool allLayerNormWeightsPresentOrNot =
3357 (((m_InputLayerNormWeights || m_Parameters.m_CifgEnabled) && m_ForgetLayerNormWeights
3358 && m_CellLayerNormWeights && m_OutputLayerNormWeights && m_Parameters.m_LayerNormEnabled)
3359 || (!m_InputLayerNormWeights && !m_ForgetLayerNormWeights && !m_CellLayerNormWeights
3360 && !m_OutputLayerNormWeights && !m_Parameters.m_LayerNormEnabled));
3362 if (!allLayerNormWeightsPresentOrNot)
3365 ": InputLayerNormWeights, ForgetLayerNormWeights, m_OutputLayerNormWeights " 3366 "and CellLayerNormWeights should all be present (Layer Norm enabled) or not " 3367 "be present at all (Layer Norm disabled). InputLayerNormWeights should " 3368 "only be present when Layer Norm is enabled and CIFG is disabled. " 3369 "m_Parameters.m_LayerNormEnabled should be set appropriately.");
3372 if (m_Parameters.m_LayerNormEnabled)
3374 auto forgetLayerNormWeightsInfo = m_ForgetLayerNormWeights->GetTensorInfo();
3376 ValidateDataTypes(forgetLayerNormWeightsInfo, layerNormPeepholeWeightsSupportedTypes, descriptorName);
3378 auto cellLayerNormWeightsInfo = m_CellLayerNormWeights->GetTensorInfo();
3380 ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, cellLayerNormWeightsInfo, descriptorName,
3381 "forgetLayerNormWeights",
"cellLayerNormWeights");
3383 auto outputLayerNormWeightsInfo = m_OutputLayerNormWeights->GetTensorInfo();
3385 ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, outputLayerNormWeightsInfo, descriptorName,
3386 "forgetLayerNormWeights",
"outputLayerNormWeights");
3388 if (!m_Parameters.m_CifgEnabled)
3390 auto inputLayerNormWeightsInfo = m_InputLayerNormWeights->GetTensorInfo();
3392 ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, inputLayerNormWeightsInfo, descriptorName,
3393 "forgetLayerNormWeights",
"inputLayerNormWeights");
3398 bool correctProjectionTensorsPresent =
3399 ((!m_ProjectionWeights && !m_ProjectionBias && !m_Parameters.m_ProjectionEnabled) ||
3400 (m_ProjectionWeights && !m_ProjectionBias && m_Parameters.m_ProjectionEnabled) ||
3401 (m_ProjectionWeights && m_ProjectionBias && m_Parameters.m_ProjectionEnabled));
3403 if (!correctProjectionTensorsPresent)
3406 ": If projection is enabled, ProjectionWeights should be present and " 3407 "ProjectionBias is optional. If projection is disabled, neither " 3408 "ProjectionWeights nor ProjectionBias should be present.");
3411 if (m_Parameters.m_ProjectionEnabled)
3413 auto projectionWeightsInfo = m_ProjectionWeights->GetTensorInfo();
3415 ValidateDataTypes(projectionWeightsInfo, weightsSupportedTypes, descriptorName);
3417 if (m_ProjectionBias)
3419 auto projectionBiasInfo = m_ProjectionBias->GetTensorInfo();
3421 ValidateDataTypes(projectionBiasInfo, biasSupportedTypes, descriptorName);
3425 else if ((outputInfo.GetQuantizationScale() != m_Parameters.m_HiddenStateScale) &&
3426 outputInfo.GetQuantizationOffset() != m_Parameters.m_HiddenStateZeroPoint) {
3428 ": If projection is disabled, output quantization info (scale, offset) " 3429 "should match HiddenStateScale and HiddenStateZeroPoint.");
3436 const std::string descriptorName{
"QuantizedLstmQueueDescriptor"};
3439 ValidateNumInputs(workloadInfo, descriptorName, 3);
3440 ValidateNumOutputs(workloadInfo, descriptorName, 2);
3450 std::vector<DataType> inputOutputSupportedTypes =
3455 std::vector<DataType> cellStateSupportedTypes =
3460 std::vector<DataType> weightsSupportedTypes =
3465 std::vector<DataType> biasSupportedTypes =
3471 ValidateDataTypes(inputInfo, inputOutputSupportedTypes, descriptorName);
3472 ValidateDataTypes(cellStateInInfo, cellStateSupportedTypes, descriptorName);
3473 ValidateDataTypes(outputStateInInfo, inputOutputSupportedTypes, descriptorName);
3475 ValidateDataTypes(cellStateOutInfo, cellStateSupportedTypes, descriptorName);
3476 ValidateDataTypes(outputStateOutInfo, inputOutputSupportedTypes, descriptorName);
3479 ValidateTensorDataTypesMatch(inputInfo, outputStateInInfo, descriptorName,
"input",
"outputStateIn");
3480 ValidateTensorDataTypesMatch(outputStateInInfo, outputStateOutInfo, descriptorName,
3481 "outputStateIn",
"outputStateOut");
3482 ValidateTensorDataTypesMatch(cellStateInInfo, cellStateOutInfo, descriptorName,
"cellStateIn",
"cellStateOut");
3485 ValidateTensorQuantizationSpace(inputInfo, outputStateInInfo, descriptorName,
"input",
"outputStateIn");
3486 ValidateTensorQuantizationSpace(inputInfo, outputStateOutInfo, descriptorName,
"input",
"outputStateOut");
3487 ValidateTensorQuantizationSpace(cellStateInInfo, cellStateOutInfo, descriptorName,
"cellStateIn",
"cellStateOut");
3490 const uint32_t numBatches = inputInfo.GetShape()[0];
3491 const uint32_t inputSize = inputInfo.GetShape()[1];
3492 const uint32_t outputSize = cellStateInInfo.GetShape()[1];
3502 ValidatePointer(m_InputToInputWeights, descriptorName,
"InputToInputWeights");
3503 auto inputToInputWeightsInfo = m_InputToInputWeights->GetTensorInfo();
3506 ValidatePointer(m_InputToForgetWeights, descriptorName,
"InputToForgetWeights");
3507 auto inputToForgetWeightsInfo = m_InputToForgetWeights->GetTensorInfo();
3510 ValidatePointer(m_InputToCellWeights, descriptorName,
"InputToCellWeights");
3511 auto inputToCellWeightsInfo = m_InputToCellWeights->GetTensorInfo();
3514 ValidatePointer(m_InputToOutputWeights, descriptorName,
"InputToOutputWeights");
3515 auto inputToOutputWeightsInfo = m_InputToOutputWeights->GetTensorInfo();
3518 ValidatePointer(m_RecurrentToInputWeights, descriptorName,
"RecurrentToInputWeights");
3519 auto recurrentToInputWeightsInfo = m_RecurrentToInputWeights->GetTensorInfo();
3522 ValidatePointer(m_RecurrentToForgetWeights, descriptorName,
"RecurrentToForgetWeights");
3523 auto recurrentToForgetWeightsInfo = m_RecurrentToForgetWeights->GetTensorInfo();
3525 " RecurrentToForgetWeights");
3527 ValidatePointer(m_RecurrentToCellWeights, descriptorName,
"RecurrentToCellWeights");
3528 auto recurrentToCellWeightsInfo = m_RecurrentToCellWeights->GetTensorInfo();
3531 ValidatePointer(m_RecurrentToOutputWeights, descriptorName,
"RecurrentToOutputWeights");
3532 auto recurrentToOutputWeightsInfo = m_RecurrentToOutputWeights->GetTensorInfo();
3536 ValidateDataTypes(inputToInputWeightsInfo, weightsSupportedTypes, descriptorName);
3538 ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToForgetWeightsInfo, descriptorName,
3539 "inputToInputWeights",
"inputToForgetWeights");
3540 ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToCellWeightsInfo, descriptorName,
3541 "inputToInputWeights",
"inputToCellWeights");
3542 ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToOutputWeightsInfo, descriptorName,
3543 "inputToInputWeights",
"inputToOutputWeights");
3545 ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToInputWeightsInfo, descriptorName,
3546 "inputToInputWeights",
"recurrentToInputWeights");
3547 ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToForgetWeightsInfo, descriptorName,
3548 "inputToInputWeights",
"recurrentToForgeteights");
3549 ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToCellWeightsInfo, descriptorName,
3550 "inputToInputWeights",
"recurrentToCellWeights");
3551 ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToOutputWeightsInfo, descriptorName,
3552 "inputToInputWeights",
"recurrentToOutputWeights");
3555 ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToForgetWeightsInfo,
3556 descriptorName,
"inputToInputWeights",
"inputToForgetWeights");
3557 ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToCellWeightsInfo,
3558 descriptorName,
"inputToInputWeights",
"inputToCellWeights");
3559 ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToOutputWeightsInfo,
3560 descriptorName,
"inputToInputWeights",
"inputToOutputWeights");
3562 ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToInputWeightsInfo,
3563 descriptorName,
"inputToInputWeights",
"recurrentToInputWeights");
3564 ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToForgetWeightsInfo,
3565 descriptorName,
"inputToInputWeights",
"recurrentToForgetWeights");
3566 ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToCellWeightsInfo,
3567 descriptorName,
"inputToInputWeights",
"recurrentToCellWeights");
3568 ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToOutputWeightsInfo,
3569 descriptorName,
"inputToInputWeights",
"recurrentToOutputWeights");
3572 ValidatePointer(m_InputGateBias, descriptorName,
"InputGateBias");
3573 auto inputGateBiasInfo = m_InputGateBias->GetTensorInfo();
3576 ValidatePointer(m_ForgetGateBias, descriptorName,
"ForgetGateBias");
3577 auto forgetGateBiasInfo = m_ForgetGateBias->GetTensorInfo();
3580 ValidatePointer(m_CellBias, descriptorName,
"CellBias");
3581 auto cellBiasInfo = m_CellBias->GetTensorInfo();
3584 ValidatePointer(m_OutputGateBias, descriptorName,
"OutputGateBias");
3585 auto outputGateBiasInfo = m_OutputGateBias->GetTensorInfo();
3589 ValidateDataTypes(inputGateBiasInfo, biasSupportedTypes, descriptorName);
3591 ValidateTensorDataTypesMatch(inputGateBiasInfo, forgetGateBiasInfo, descriptorName,
3592 "inputGateBias",
"forgetGateBias");
3593 ValidateTensorDataTypesMatch(inputGateBiasInfo, cellBiasInfo, descriptorName,
3594 "inputGateBias",
"cellBias");
3595 ValidateTensorDataTypesMatch(inputGateBiasInfo, outputGateBiasInfo, descriptorName,
3596 "inputGateBias",
"outputGateBias");
3599 ValidateBiasTensorQuantization(inputGateBiasInfo, inputInfo, inputToInputWeightsInfo, descriptorName);
3600 ValidateBiasTensorQuantization(forgetGateBiasInfo, inputInfo, inputToInputWeightsInfo, descriptorName);
3601 ValidateBiasTensorQuantization(cellBiasInfo, inputInfo, inputToInputWeightsInfo, descriptorName);
3602 ValidateBiasTensorQuantization(outputGateBiasInfo, inputInfo, inputToInputWeightsInfo, descriptorName);
3607 const std::string descriptorName{
"AbsQueueDescriptor"};
3609 ValidateNumInputs(workloadInfo, descriptorName, 1);
3610 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3615 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3617 std::vector<DataType> supportedTypes =
3628 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3629 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3634 const std::string descriptorName{
"SliceQueueDescriptor"};
3636 ValidateNumInputs(workloadInfo, descriptorName, 1);
3637 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3642 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3653 if (m_Parameters.m_Begin.size() != rank)
3656 ": Length of begin offset descriptor must equal rank " + std::to_string(rank));
3658 if (m_Parameters.m_Size.size() != rank)
3661 ": Length of size descriptor must equal rank " + std::to_string(rank));
3666 for (
unsigned int i = 0u; i < rank; ++i)
3668 if (m_Parameters.m_Size[i] != outputShape[i])
3677 for(
unsigned int i = 0u; i < rank; ++i)
3679 if (m_Parameters.m_Begin[i] + m_Parameters.m_Size[i] > inputShape[i])
3682 std::to_string(i) +
" exceeds input size.");
3689 const std::string descriptorName{
"DepthToSpaceQueueDescriptor"};
3691 ValidateNumInputs(workloadInfo, descriptorName, 1);
3692 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3700 std::vector<DataType> supportedTypes =
3710 ValidateDataTypes(inputInfo, supportedTypes, descriptorName);
3711 ValidateDataTypes(outputInfo, supportedTypes, descriptorName);
3713 ValidateTensorNumElementsMatch(inputInfo, outputInfo, descriptorName,
"input",
"output");
3715 if (m_Parameters.m_BlockSize == 0)
3721 const unsigned int wIndex = dimensionIndices.
GetWidthIndex();
3726 if (outputShape[hIndex] % m_Parameters.m_BlockSize != 0 || outputShape[wIndex] % m_Parameters.m_BlockSize != 0)
3729 "must be divisible by block size.");
3733 if (inputShape[cIndex] % (m_Parameters.m_BlockSize * m_Parameters.m_BlockSize) != 0)
3736 "must be divisible by the square of block size." );
3742 const std::string descriptorName{
"ComparisonQueueDescriptor"};
3744 ValidateNumInputs(workloadInfo, descriptorName, 2);
3745 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3751 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
3766 const std::string descriptorName{
"ElementwiseUnaryQueueDescriptor"};
3768 ValidateNumInputs(workloadInfo, descriptorName, 1);
3769 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3774 ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3776 std::vector<DataType> supportedTypes =
3787 std::vector<DataType> logicalSupportedTypes =
3794 ValidateDataTypes(inputTensorInfo, logicalSupportedTypes, descriptorName);
3798 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3802 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3807 const std::string descriptorName{
"RankQueueDescriptor"};
3809 ValidateNumInputs(workloadInfo, descriptorName, 1);
3810 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3816 ValidateTensorNumElements(outputTensorInfo, descriptorName, 1,
"output");
3818 std::vector<DataType> supportedTypes =
3830 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3831 ValidateDataTypes(outputTensorInfo, { DataType::Signed32 }, descriptorName);
3836 const std::string descriptorName{
"LogicalBinaryQueueDescriptor"};
3838 ValidateNumInputs(workloadInfo, descriptorName, 2);
3839 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3845 ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
3870 const std::string descriptorName{
"ReduceQueueDescriptor"};
3872 ValidateNumInputs(workloadInfo, descriptorName, 1);
3873 ValidateNumOutputs(workloadInfo, descriptorName, 1);
3878 std::vector<DataType> supportedTypes =
3889 ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3890 ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName,
"input",
"output");
3897 const std::string descriptorName{
"UnidirectionalSequenceLstmQueueDescriptor"};
3909 std::vector<DataType> supportedTypes =
3916 ValidateDataTypes(workloadInfo.
m_InputTensorInfos[0], supportedTypes, descriptorName);
3921 if (m_Parameters.m_ClippingThresCell < 0.0f)
3925 if (m_Parameters.m_ClippingThresProj < 0.0f)
3930 unsigned int batchIndx = 0;
3931 unsigned int inputIndx = 1;
3932 uint32_t timeStep = 1;
3933 unsigned int timeIndx = 1;
3935 if (m_Parameters.m_TimeMajor)
3946 ValidatePointer(m_InputToOutputWeights,
"Null pointer check",
"InputToOutputWeights");
3947 const uint32_t n_cell = m_InputToOutputWeights->GetShape()[0];
3948 ValidatePointer(m_RecurrentToOutputWeights,
"Null pointer check",
"RecurrentToOutputWeights");
3949 const uint32_t n_output = m_RecurrentToOutputWeights->GetShape()[1];
3953 descriptorName +
" input_0");
3956 descriptorName +
" input_1");
3959 descriptorName +
" input_2");
3963 descriptorName +
" output_0");
3966 if ( m_InputToInputWeights )
3969 (n_cell * n_input),
"InputLayerNormWeights");
3972 ValidatePointer(m_InputToForgetWeights,
"Null pointer check",
"InputToForgetWeights");
3974 (n_cell * n_input),
"InputToForgetWeights");
3976 ValidatePointer(m_InputToCellWeights,
"Null pointer check",
"InputToCellWeights");
3978 (n_cell * n_input),
"InputToCellWeights");
3980 if ( m_RecurrentToInputWeights )
3983 (n_cell * n_output),
"RecurrentToInputWeights");
3986 ValidatePointer(m_RecurrentToForgetWeights,
"Null pointer check",
"RecurrentToForgetWeights");
3988 (n_cell * n_output),
"RecurrentToForgetWeights");
3990 ValidatePointer(m_RecurrentToCellWeights,
"Null pointer check",
"RecurrentToCellWeights");
3992 (n_cell * n_output),
"RecurrentToCellWeights");
3996 bool cifg_weights_all_or_none = ((m_InputToInputWeights && m_RecurrentToInputWeights &&
3997 !m_Parameters.m_CifgEnabled) ||
3998 (!m_InputToInputWeights && !m_RecurrentToInputWeights &&
3999 m_Parameters.m_CifgEnabled));
4000 if (!cifg_weights_all_or_none)
4003 "RecurrentToInputWeights must either both be present (regular LSTM) " 4004 "or both not present (CIFG-LSTM). In addition CifgEnable must be set " 4008 if ( m_CellToInputWeights )
4011 n_cell,
"CellToInputWeights");
4013 if ( m_CellToForgetWeights )
4016 n_cell,
"CellToForgetWeights");
4018 if ( m_CellToOutputWeights )
4021 n_cell,
"CellToOutputWeights");
4025 bool peephole_weights_all_or_none =
4026 (((m_CellToInputWeights || m_Parameters.m_CifgEnabled) && m_CellToForgetWeights
4027 && m_CellToOutputWeights && m_Parameters.m_PeepholeEnabled)
4028 || ( !m_CellToInputWeights && !m_CellToForgetWeights
4029 && !m_CellToOutputWeights && !m_Parameters.m_PeepholeEnabled));
4030 if (!peephole_weights_all_or_none)
4036 if (m_Parameters.m_CifgEnabled)
4038 if (m_InputGateBias)
4045 if (!m_InputGateBias)
4048 "must be present.");
4051 n_cell,
"InputGateBias");
4054 ValidatePointer(m_ForgetGateBias,
"Null pointer check",
"ForgetGateBias");
4057 ValidatePointer(m_CellBias,
"Null pointer check",
"CellBias");
4060 ValidatePointer(m_OutputGateBias,
"Null pointer check",
"OutputGateBias");
4063 if (m_ProjectionWeights)
4066 (n_cell * n_output),
"ProjectionWeights");
4068 if (m_ProjectionBias)
4077 bool projecton_tensors_consistent = ((!m_ProjectionWeights && !m_ProjectionBias &&
4078 !m_Parameters.m_ProjectionEnabled)
4079 || (m_ProjectionWeights && !m_ProjectionBias &&
4080 m_Parameters.m_ProjectionEnabled)
4081 || (m_ProjectionWeights && m_ProjectionBias &&
4082 m_Parameters.m_ProjectionEnabled));
4083 if (!projecton_tensors_consistent)
4092 if (m_InputLayerNormWeights)
4096 if (m_ForgetLayerNormWeights)
4100 if (m_CellLayerNormWeights)
4104 if (m_OutputLayerNormWeights)
4109 if (m_Parameters.m_LayerNormEnabled)
4111 if (!m_Parameters.m_CifgEnabled)
4113 if (!m_InputLayerNormWeights)
4116 "disabled but InputLayerNormWeights are not present");
4119 1, n_cell,
"InputLayerNormWeights");
4121 else if (m_InputLayerNormWeights)
4127 ValidatePointer(m_ForgetLayerNormWeights,
"Null pointer check layer normalisation enabled",
4128 "ForgetLayerNormWeights");
4131 ValidatePointer(m_OutputLayerNormWeights,
"Null pointer check layer normalisation enabled",
4132 "OutputLayerNormWeights");
4135 ValidatePointer(m_CellLayerNormWeights,
"Null pointer check layer normalisation enabled",
4136 "CellLayerNormWeights");
4139 else if (m_InputLayerNormWeights || m_ForgetLayerNormWeights || m_OutputLayerNormWeights || m_CellLayerNormWeights)
4142 "normalisation weights are present.");
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
bool IsTypeSpaceMatch(const TensorInfo &other) const
Check that the types are the same and, if quantize, that the quantization parameters are the same...
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
unsigned int GetWidthIndex() const
std::vector< unsigned int > m_Origin
const TensorShape & GetShape() const
constexpr bool IsQuantizedType()
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
bool HasPerAxisQuantization() const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void ValidateTensorNumDimNumElem(const TensorInfo &tensorInfo, unsigned int numDimension, unsigned int numElements, std::string const &tensorName) const
void Validate(const WorkloadInfo &workloadInfo) const
Optional< unsigned int > GetQuantizationDim() const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
#define ARMNN_LOG(severity)
void ValidateInputsOutputs(const std::string &descName, unsigned int numExpectedIn, unsigned int numExpectedOut) const
Copyright (c) 2021 ARM Limited and Contributors.
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
std::vector< float > GetQuantizationScales() const
bool HasMultipleQuantizationScales() const
void Validate(const WorkloadInfo &workloadInfo) const
unsigned int GetHeightIndex() const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
constexpr const char * GetDataTypeName(DataType dataType)
constexpr bool IsQuantized8BitType(DataType dataType)
void Validate(const WorkloadInfo &workloadInfo) const
std::vector< TensorInfo > m_InputTensorInfos
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
#define ARMNN_ASSERT_MSG(COND, MSG)
void Validate(const WorkloadInfo &workloadInfo) const
int32_t GetQuantizationOffset() const
float GetQuantizationScale() const
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout...
DataType GetDataType() const
bool has_value() const noexcept
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
unsigned int GetUnsignedAxis(const unsigned int inputDimension, const int axis)
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
std::vector< TensorInfo > m_OutputTensorInfos
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
DataType GetBiasDataType(DataType inputDataType)
void Validate(const WorkloadInfo &workloadInfo) const
void ValidateTensorNumDimensions(const TensorInfo &tensor, std::string const &descName, unsigned int numDimensions, std::string const &tensorName) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
std::vector< ITensorHandle * > m_Outputs
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
Contains information about TensorInfos of a layer.
void Validate(const WorkloadInfo &workloadInfo) const
std::vector< ITensorHandle * > m_Inputs
void Validate(const WorkloadInfo &workloadInfo) const
void Validate(const WorkloadInfo &workloadInfo) const
unsigned int GetNumDimensions() const
unsigned int GetChannelsIndex() const
void Validate(const WorkloadInfo &workloadInfo) const
unsigned int GetNumElements() const
void Validate(const WorkloadInfo &workloadInfo) const
std::vector< unsigned int > m_Origin