22 #include <doctest/doctest.h> 26 using namespace armnn;
34 template<
typename Workload>
35 std::unique_ptr<Workload> MakeAndCheckWorkload(
Layer& layer,
39 std::unique_ptr<IWorkload> workload = layer.
CreateWorkload(factory);
40 CHECK_MESSAGE(workload.get() == PolymorphicDowncast<Workload*>(workload.get()),
41 "Cannot convert to derived class");
42 std::string reasonIfUnsupported;
45 return std::unique_ptr<Workload>(
static_cast<Workload*
>(workload.release()));
66 template <
typename ActivationWorkload, armnn::DataType DataType>
74 layerDesc.
m_B = -10.0f;
85 Connect(input, layer, tensorInfo);
86 Connect(layer, output, tensorInfo);
88 CreateTensorHandles(graph, factory);
91 auto workload = MakeAndCheckWorkload<ActivationWorkload>(*layer, factory);
94 CHECK(queueDescriptor.m_Inputs.size() == 1);
95 CHECK(queueDescriptor.m_Outputs.size() == 1);
96 CHECK(queueDescriptor.m_Parameters.m_A == 3.5f);
97 CHECK(queueDescriptor.m_Parameters.m_B == -10.0f);
104 template <
typename WorkloadType,
105 typename DescriptorType,
121 Connect(input1, layer, tensorInfo, 0, 0);
122 Connect(input2, layer, tensorInfo, 0, 1);
123 Connect(layer, output, tensorInfo);
124 CreateTensorHandles(graph, factory);
127 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
129 DescriptorType queueDescriptor = workload->GetData();
130 CHECK(queueDescriptor.m_Inputs.size() == 2);
131 CHECK(queueDescriptor.m_Outputs.size() == 1);
137 template<
typename WorkloadType,
138 typename DescriptorType,
146 auto activationDesc = std::make_shared<ActivationDescriptor>();
147 activationDesc->m_A = 10.0f;
148 activationDesc->m_B = 5.0f;
160 Connect(input1, layer, tensorInfo, 0, 0);
161 Connect(input2, layer, tensorInfo, 0, 1);
162 Connect(layer, output, tensorInfo);
163 CreateTensorHandles(graph, factory);
166 std::shared_ptr<ActivationDescriptor>
169 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
170 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
176 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
178 DescriptorType queueDescriptor = workload->GetData();
181 queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
189 CHECK(queueDescriptor.m_Inputs.size() == 2);
190 CHECK(queueDescriptor.m_Outputs.size() == 1);
195 template<
typename WorkloadType,
196 typename DescriptorType,
204 auto activationDesc = std::make_shared<ActivationDescriptor>();
205 activationDesc->m_A = 10.0f;
206 activationDesc->m_B = 5.0f;
218 Connect(input1, layer, tensorInfo, 0, 0);
219 Connect(input2, layer, tensorInfo, 0, 1);
220 Connect(layer, output, tensorInfo);
221 CreateTensorHandles(graph, factory);
224 std::shared_ptr<ActivationDescriptor>
227 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
228 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
234 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
236 DescriptorType queueDescriptor = workload->GetData();
237 CHECK(queueDescriptor.m_Inputs.size() == 2);
238 CHECK(queueDescriptor.m_Outputs.size() == 1);
240 queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
242 ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
243 ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
251 template<
typename WorkloadType,
252 typename DescriptorType,
260 auto activationDesc = std::make_shared<ActivationDescriptor>();
261 activationDesc->m_A = 10.0f;
262 activationDesc->m_B = 5.0f;
274 Connect(input1, layer, tensorInfo, 0, 0);
275 Connect(input2, layer, tensorInfo, 0, 1);
276 Connect(layer, output, tensorInfo);
277 CreateTensorHandles(graph, factory);
280 std::shared_ptr<ActivationDescriptor>
281 activationDescPtr = layer->template GetAdditionalInformation<ActivationDescriptor>();
283 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
284 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
290 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
292 DescriptorType queueDescriptor = workload->GetData();
294 queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
296 CHECK(queueDescriptor.m_Inputs.size() == 2);
297 CHECK(queueDescriptor.m_Outputs.size() == 1);
307 template <
typename WorkloadType,
308 typename DescriptorType,
321 Connect(input, layer, tensorInfo, 0, 0);
322 Connect(layer, output, tensorInfo, 0, 0);
323 CreateTensorHandles(graph, factory);
325 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
326 DescriptorType queueDescriptor = workload->GetData();
328 CHECK(queueDescriptor.m_Inputs.size() == 1);
329 CHECK(queueDescriptor.m_Outputs.size() == 1);
334 template <
typename BatchNormalizationWorkloadType, armnn::DataType DataType>
335 std::unique_ptr<BatchNormalizationWorkloadType> CreateBatchNormalizationWorkloadTest(
342 tensorShape = { 2, 4, 4, 3 };
346 tensorShape = { 2, 3, 4, 4 };
351 layerDesc.
m_Eps = 0.05f;
357 layer->
m_Mean = std::make_unique<ScopedTensorHandle>(weightInfo);
358 layer->
m_Variance = std::make_unique<ScopedTensorHandle>(weightInfo);
359 layer->
m_Beta = std::make_unique<ScopedTensorHandle>(weightInfo);
360 layer->
m_Gamma = std::make_unique<ScopedTensorHandle>(weightInfo);
361 layer->
m_Mean->Allocate();
363 layer->
m_Beta->Allocate();
372 Connect(input, layer, tensorInfo);
373 Connect(layer, output, tensorInfo);
374 CreateTensorHandles(graph, factory);
377 auto workload = MakeAndCheckWorkload<BatchNormalizationWorkloadType>(*layer, factory);
379 CHECK(queueDescriptor.m_Parameters.m_Eps == 0.05f);
380 CHECK(queueDescriptor.m_Inputs.size() == 1);
381 CHECK(queueDescriptor.m_Outputs.size() == 1);
386 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
392 template <
typename BatchNormalizationWorkloadType, armnn::DataType DataType>
393 std::unique_ptr<BatchNormalizationWorkloadType> CreateBatchNormalizationWithBlobWorkloadTest(
400 tensorShape = { 2, 4, 4, 3 };
404 tensorShape = { 2, 3, 4, 4 };
409 layerDesc.
m_Eps = 0.05f;
415 layer->
m_Mean = std::make_unique<ScopedTensorHandle>(weightInfo);
416 layer->
m_Variance = std::make_unique<ScopedTensorHandle>(weightInfo);
417 layer->
m_Beta = std::make_unique<ScopedTensorHandle>(weightInfo);
418 layer->
m_Gamma = std::make_unique<ScopedTensorHandle>(weightInfo);
419 layer->
m_Mean->Allocate();
421 layer->
m_Beta->Allocate();
424 auto activationDesc = std::make_shared<ActivationDescriptor>();
425 activationDesc->m_A = 10.0f;
426 activationDesc->m_B = 5.0f;
433 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
434 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
445 Connect(input, layer, tensorInfo);
446 Connect(layer, output, tensorInfo);
447 CreateTensorHandles(graph, factory);
450 auto workload = MakeAndCheckWorkload<BatchNormalizationWorkloadType>(*layer, factory);
460 CHECK(queueDescriptor.m_Parameters.m_Eps == 0.05f);
461 CHECK(queueDescriptor.m_Inputs.size() == 1);
462 CHECK(queueDescriptor.m_Outputs.size() == 1);
467 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
473 template <
typename Convolution2dWorkload, armnn::DataType DataType>
500 layer->
m_Bias->Allocate();
509 CreateTensorHandles(graph, factory);
512 auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
515 CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
516 CHECK(queueDescriptor.m_Parameters.m_StrideY == 4);
517 CHECK(queueDescriptor.m_Parameters.m_PadLeft == 3);
518 CHECK(queueDescriptor.m_Parameters.m_PadRight == 3);
519 CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
520 CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
521 CHECK(queueDescriptor.m_Parameters.m_BiasEnabled);
522 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
524 CHECK(queueDescriptor.m_Inputs.size() == 1);
525 CHECK(queueDescriptor.m_Outputs.size() == 1);
526 CHECK((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo(weightShape,
DataType)));
527 CHECK((queueDescriptor.m_Bias->GetTensorInfo() ==
534 template<
typename Convolution2dWorkload, armnn::DataType DataType>
535 std::unique_ptr<Convolution2dWorkload> CreateConvolution2dFusedActivationWithBlobWorkloadTest(
563 layer->
m_Bias->Allocate();
565 auto activationDesc = std::make_shared<ActivationDescriptor>();
566 activationDesc->m_A = 10.0f;
567 activationDesc->m_B = 5.0f;
575 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
576 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
588 CreateTensorHandles(graph, factory);
591 auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
602 CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
603 CHECK(queueDescriptor.m_Parameters.m_StrideY == 4);
604 CHECK(queueDescriptor.m_Parameters.m_PadLeft == 3);
605 CHECK(queueDescriptor.m_Parameters.m_PadRight == 3);
606 CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
607 CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
608 CHECK(queueDescriptor.m_Parameters.m_BiasEnabled);
609 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
610 CHECK(queueDescriptor.m_Outputs.size() == 1);
611 CHECK((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo(weightShape,
DataType)));
612 CHECK((queueDescriptor.m_Bias->GetTensorInfo() ==
614 CHECK(queueDescriptor.m_Inputs.size() == 1);
620 template <
typename Convolution2dWorkload, armnn::DataType DataType>
621 std::unique_ptr<Convolution2dWorkload> CreateConvolution2dWorkloadFastMathTest(
armnn::IWorkloadFactory& factory,
647 layer->
m_Bias->Allocate();
656 CreateTensorHandles(graph, factory);
659 auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
662 CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
663 CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
664 CHECK(queueDescriptor.m_Parameters.m_PadLeft == 0);
665 CHECK(queueDescriptor.m_Parameters.m_PadRight == 0);
666 CHECK(queueDescriptor.m_Parameters.m_PadTop == 0);
667 CHECK(queueDescriptor.m_Parameters.m_PadBottom == 0);
668 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
670 CHECK(queueDescriptor.m_Inputs.size() == 1);
671 CHECK(queueDescriptor.m_Outputs.size() == 1);
672 CHECK((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo(weightShape,
DataType)));
678 template <
typename LstmWorkload>
691 unsigned int batchSize = 2;
692 unsigned int inputSize = 2;
693 unsigned int numUnits = 4;
694 unsigned int outputSize = 4;
726 if (layerDesc.m_PeepholeEnabled)
749 armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * (layerDesc.m_CifgEnabled ? 3 : 4) },
751 Connect(input, layer, lstmTensorInfo1, 0, 0);
752 Connect(cellStateIn, layer, lstmTensorInfo2, 0, 1);
753 Connect(outputStateIn, layer, lstmTensorInfo3, 0, 2);
754 Connect(layer, scratchBuffer, lstmTensorInfoScratchBuff, 0, 0);
755 Connect(layer, outputStateOut, lstmTensorInfo3, 1, 0);
756 Connect(layer, cellStateOut, lstmTensorInfo2, 2, 0);
757 Connect(layer, output, lstmTensorInfo3, 3, 0);
759 CreateTensorHandles(graph, factory);
762 auto workload = MakeAndCheckWorkload<LstmWorkload>(*layer, factory);
764 CHECK(queueDescriptor.m_Parameters.m_ActivationFunc == 4);
765 CHECK(queueDescriptor.m_Parameters.m_ClippingThresCell == 0.0f);
766 CHECK(queueDescriptor.m_Parameters.m_ClippingThresProj == 0.0f);
767 CHECK(queueDescriptor.m_Inputs.size() == 3);
768 CHECK(queueDescriptor.m_Outputs.size() == 4);
770 CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() ==
TensorInfo({ numUnits, inputSize },
772 CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() ==
TensorInfo({ numUnits },
778 template <
typename QuantizedLstmWorkload>
783 unsigned int numBatches = 2;
784 unsigned int inputSize = 2;
785 unsigned int outputSize = 4;
788 float inputOutputScale = 0.0078125f;
789 int32_t inputOutputOffset = 128;
791 float cellStateScale = 0.00048828125f;
792 int32_t cellStateOffset = 0;
794 float weightsScale = 0.00408021f;
795 int32_t weightsOffset = 100;
797 float biasScale = 3.1876640625e-05f;
798 int32_t biasOffset = 0;
817 layer->m_QuantizedLstmParameters.m_InputToInputWeights =
818 std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
819 layer->m_QuantizedLstmParameters.m_InputToForgetWeights =
820 std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
821 layer->m_QuantizedLstmParameters.m_InputToCellWeights =
822 std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
823 layer->m_QuantizedLstmParameters.m_InputToOutputWeights =
824 std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
826 layer->m_QuantizedLstmParameters.m_RecurrentToInputWeights =
827 std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
828 layer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights =
829 std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
830 layer->m_QuantizedLstmParameters.m_RecurrentToCellWeights =
831 std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
832 layer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights =
833 std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
835 layer->m_QuantizedLstmParameters.m_InputGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
836 layer->m_QuantizedLstmParameters.m_ForgetGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
837 layer->m_QuantizedLstmParameters.m_CellBias = std::make_unique<ScopedTensorHandle>(biasInfo);
838 layer->m_QuantizedLstmParameters.m_OutputGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
841 layer->m_QuantizedLstmParameters.m_InputToInputWeights->Allocate();
842 layer->m_QuantizedLstmParameters.m_InputToForgetWeights->Allocate();
843 layer->m_QuantizedLstmParameters.m_InputToCellWeights->Allocate();
844 layer->m_QuantizedLstmParameters.m_InputToOutputWeights->Allocate();
846 layer->m_QuantizedLstmParameters.m_RecurrentToInputWeights->Allocate();
847 layer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights->Allocate();
848 layer->m_QuantizedLstmParameters.m_RecurrentToCellWeights->Allocate();
849 layer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights->Allocate();
851 layer->m_QuantizedLstmParameters.m_InputGateBias->Allocate();
852 layer->m_QuantizedLstmParameters.m_ForgetGateBias->Allocate();
853 layer->m_QuantizedLstmParameters.m_CellBias->Allocate();
854 layer->m_QuantizedLstmParameters.m_OutputGateBias->Allocate();
881 Connect(input, layer, inputInfo, 0, 0);
882 Connect(cellStateIn, layer, cellStateInfo, 0, 1);
883 Connect(outputStateIn, layer, outputStateInfo, 0, 2);
885 Connect(layer, cellStateOut, cellStateInfo, 0, 0);
886 Connect(layer, outputStateOut, outputStateInfo, 1, 0);
888 CreateTensorHandles(graph, factory);
891 auto workload = MakeAndCheckWorkload<QuantizedLstmWorkload>(*layer, factory);
895 CHECK(queueDescriptor.m_Inputs.size() == 3);
896 CHECK(queueDescriptor.m_Outputs.size() == 2);
899 CHECK((queueDescriptor.m_InputToInputWeights->GetTensorInfo() == inputWeightsInfo));
900 CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == inputWeightsInfo));
901 CHECK((queueDescriptor.m_InputToCellWeights->GetTensorInfo() == inputWeightsInfo));
902 CHECK((queueDescriptor.m_InputToOutputWeights->GetTensorInfo() == inputWeightsInfo));
904 CHECK((queueDescriptor.m_RecurrentToInputWeights->GetTensorInfo() == recurrentWeightsInfo));
905 CHECK((queueDescriptor.m_RecurrentToForgetWeights->GetTensorInfo() == recurrentWeightsInfo));
906 CHECK((queueDescriptor.m_RecurrentToCellWeights->GetTensorInfo() == recurrentWeightsInfo));
907 CHECK((queueDescriptor.m_RecurrentToOutputWeights->GetTensorInfo() == recurrentWeightsInfo));
909 CHECK((queueDescriptor.m_InputGateBias->GetTensorInfo() == biasInfo));
910 CHECK((queueDescriptor.m_ForgetGateBias->GetTensorInfo() == biasInfo));
911 CHECK((queueDescriptor.m_CellBias->GetTensorInfo() == biasInfo));
912 CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() == biasInfo));
917 template <
typename QLstmWorkload>
940 unsigned int numBatches = 2;
941 unsigned int inputSize = 4;
942 unsigned int numUnits = 4;
943 unsigned int outputSize = 4;
946 float inputScale = 0.0078125f;
947 int32_t inputOffset = 0;
950 float outputScale = layerDesc.m_HiddenStateScale;
951 int32_t outputOffset = layerDesc.m_HiddenStateZeroPoint;
953 float cellStateScale = 3.05176e-05f;
954 int32_t cellStateOffset = 0;
956 float weightsScale = 0.00784314f;
957 int32_t weightsOffset = 0;
959 float layerNormScale = 3.05182e-05f;
960 int32_t layerNormOffset = 0;
962 float biasScale = layerNormScale / 1024;
963 int32_t biasOffset = 0;
986 std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
988 std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
990 std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
997 std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
999 std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
1001 std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
1045 Connect(input, layer, inputInfo, 0, 0);
1046 Connect(outputStateIn, layer, outputStateInfo, 0, 1);
1047 Connect(cellStateIn, layer, cellStateInfo, 0, 2);
1049 Connect(layer, outputStateOut, outputStateInfo, 0, 0);
1050 Connect(layer, cellStateOut, cellStateInfo, 1, 0);
1051 Connect(layer, output, outputStateInfo, 2, 0);
1053 CreateTensorHandles(graph, factory);
1056 auto workload = MakeAndCheckWorkload<QLstmWorkload>(*layer, factory);
1058 CHECK(queueDescriptor.m_Parameters.m_CellClip == 0.0f);
1059 CHECK(queueDescriptor.m_Parameters.m_ProjectionClip == 0.0f);
1060 CHECK(queueDescriptor.m_Inputs.size() == 3);
1061 CHECK(queueDescriptor.m_Outputs.size() == 3);
1063 CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == inputWeightsInfo));
1064 CHECK((queueDescriptor.m_InputToCellWeights->GetTensorInfo() == inputWeightsInfo));
1065 CHECK((queueDescriptor.m_InputToOutputWeights->GetTensorInfo() == inputWeightsInfo));
1067 CHECK((queueDescriptor.m_RecurrentToForgetWeights->GetTensorInfo() == recurrentWeightsInfo));
1068 CHECK((queueDescriptor.m_RecurrentToCellWeights->GetTensorInfo() == recurrentWeightsInfo));
1069 CHECK((queueDescriptor.m_RecurrentToOutputWeights->GetTensorInfo() == recurrentWeightsInfo));
1071 CHECK((queueDescriptor.m_ForgetGateBias->GetTensorInfo() == biasInfo));
1072 CHECK((queueDescriptor.m_CellBias->GetTensorInfo() == biasInfo));
1073 CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() == biasInfo));
1078 template <
typename Convolution2dWorkload, armnn::DataType DataType>
1079 std::unique_ptr<Convolution2dWorkload> CreateDirectConvolution2dWorkloadTest(
armnn::IWorkloadFactory& factory,
1094 float inputsQScale =
DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
1095 float outputQScale =
DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
1098 layer->
m_Bias = std::make_unique<ScopedTensorHandle>
1101 layer->
m_Bias->Allocate();
1110 CreateTensorHandles(graph, factory);
1113 auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory);
1116 CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
1117 CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
1118 CHECK(queueDescriptor.m_Parameters.m_PadLeft == 1);
1119 CHECK(queueDescriptor.m_Parameters.m_PadRight == 1);
1120 CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
1121 CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
1122 CHECK(queueDescriptor.m_Parameters.m_BiasEnabled ==
true);
1124 CHECK(queueDescriptor.m_Inputs.size() == 1);
1125 CHECK(queueDescriptor.m_Outputs.size() == 1);
1126 CHECK((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo({2, 3, 3, 3},
1128 CHECK((queueDescriptor.m_Bias->GetTensorInfo()
1135 template <
typename DepthwiseConvolution2dFloat32Workload, armnn::DataType DataType>
1136 std::unique_ptr<DepthwiseConvolution2dFloat32Workload> CreateDepthwiseConvolution2dWorkloadTest(
1167 CreateTensorHandles(graph, factory);
1170 auto workload = MakeAndCheckWorkload<DepthwiseConvolution2dFloat32Workload>(*layer, factory);
1173 CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
1174 CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
1175 CHECK(queueDescriptor.m_Parameters.m_PadLeft == 1);
1176 CHECK(queueDescriptor.m_Parameters.m_PadRight == 2);
1177 CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
1178 CHECK(queueDescriptor.m_Parameters.m_PadBottom == 2);
1179 CHECK(queueDescriptor.m_Parameters.m_BiasEnabled ==
false);
1180 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
1182 CHECK(queueDescriptor.m_Inputs.size() == 1);
1183 CHECK(queueDescriptor.m_Outputs.size() == 1);
1184 CHECK((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo({1, 4, 4, 2},
DataType)));
1190 template <
typename FullyConnectedWorkload, armnn::DataType DataType>
1201 float inputsQScale =
DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
1202 float outputQScale =
DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
1216 weights->m_LayerOutput = std::make_unique<ScopedTensorHandle>(weightsTensorInfo);
1217 weights->m_LayerOutput->Allocate();
1221 Connect(weights, layer, weightsTensorInfo, 0, 1);
1223 CreateTensorHandles(graph, factory);
1226 auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
1229 CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix ==
true);
1231 CHECK(queueDescriptor.m_Inputs.size() == 2);
1232 CHECK(queueDescriptor.m_Outputs.size() == 1);
1238 template <
typename FullyConnectedWorkload, armnn::DataType DataType>
1239 std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWithBlobWorkloadTest
1250 float inputsQScale =
DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
1251 float outputQScale =
DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
1257 layer->
m_Bias->Allocate();
1262 biasesTensorInfo.SetConstant();
1264 auto activationDesc = std::make_shared<ActivationDescriptor>();
1265 activationDesc->m_A = 10.0f;
1266 activationDesc->m_B = 5.0f;
1273 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
1274 ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
1275 ARMNN_ASSERT(static_cast<ActivationFunction>(activationDescPtr->m_Function) ==
1284 weights->m_LayerOutput = std::make_unique<ScopedTensorHandle>(weightsTensorInfo);
1285 weights->m_LayerOutput->Allocate();
1286 biases->
m_LayerOutput = std::make_unique<ScopedTensorHandle>(biasesTensorInfo);
1291 Connect(weights, layer, weightsTensorInfo, 0, 1);
1292 Connect(biases, layer, biasesTensorInfo, 0, 2);
1294 CreateTensorHandles(graph, factory);
1297 auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
1310 CHECK(queueDescriptor.m_Parameters.m_BiasEnabled ==
true);
1311 CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix ==
true);
1312 CHECK(queueDescriptor.m_Inputs.size() == 3);
1313 CHECK(queueDescriptor.m_Outputs.size() == 1);
1319 template <
typename FullyConnectedWorkload, armnn::DataType DataType>
1320 std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWorkloadWeightsBiasesAsInputsTest
1332 float inputsQScale =
DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
1333 float outputQScale =
DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
1346 CreateTensorHandles(graph, factory);
1349 auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
1353 CHECK(queueDescriptor.m_Parameters.m_BiasEnabled ==
true);
1354 CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix ==
true);
1355 CHECK(queueDescriptor.m_Parameters.m_ConstantWeights ==
false);
1356 CHECK(queueDescriptor.m_Inputs.size() == 3);
1357 CHECK(queueDescriptor.m_Outputs.size() == 1);
1364 template <
typename NormalizationWorkload, armnn::DataType DataType>
1375 layerDesc.
m_Beta = -1.0f;
1376 layerDesc.
m_K = 0.2f;
1393 Connect(input, layer, inputTensorInfo);
1394 Connect(layer, output, outputTensorInfo);
1395 CreateTensorHandles(graph, factory);
1398 auto workload = MakeAndCheckWorkload<NormalizationWorkload>(*layer, factory);
1403 CHECK(queueDescriptor.m_Parameters.m_NormSize == 3);
1404 CHECK(queueDescriptor.m_Parameters.m_Alpha == 0.5f);
1405 CHECK(queueDescriptor.m_Parameters.m_Beta == -1.0f);
1406 CHECK(queueDescriptor.m_Parameters.m_K == 0.2f);
1407 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
1409 CHECK(queueDescriptor.m_Inputs.size() == 1);
1410 CHECK(queueDescriptor.m_Outputs.size() == 1);
1416 template <
typename Pooling2dWorkload, armnn::DataType DataType>
1447 CreateTensorHandles(graph, factory);
1450 auto workload = MakeAndCheckWorkload<Pooling2dWorkload>(*layer, factory);
1455 CHECK(queueDescriptor.m_Parameters.m_PoolWidth == 3);
1456 CHECK(queueDescriptor.m_Parameters.m_PoolHeight == 3);
1457 CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
1458 CHECK(queueDescriptor.m_Parameters.m_StrideY == 3);
1459 CHECK(queueDescriptor.m_Parameters.m_PadLeft == 2);
1460 CHECK(queueDescriptor.m_Parameters.m_PadRight == 2);
1461 CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
1462 CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
1463 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
1465 CHECK(queueDescriptor.m_Inputs.size() == 1);
1466 CHECK(queueDescriptor.m_Outputs.size() == 1);
1472 template <
typename SoftmaxWorkload, armnn::DataType DataType>
1481 softmaxDescriptor.
m_Axis = -1;
1491 if (
DataType == armnn::DataType::QAsymmU8)
1494 tensorInfo.SetQuantizationScale(1.f / 256);
1496 else if (
DataType == armnn::DataType::QAsymmS8)
1498 tensorInfo.SetQuantizationOffset(-128);
1499 tensorInfo.SetQuantizationScale(1.f / 256);
1502 Connect(input, layer, tensorInfo);
1503 Connect(layer, output, tensorInfo);
1504 CreateTensorHandles(graph, factory);
1507 auto workload = MakeAndCheckWorkload<SoftmaxWorkload>(*layer, factory);
1510 CHECK(queueDescriptor.m_Inputs.size() == 1);
1511 CHECK(queueDescriptor.m_Outputs.size() == 1);
1517 template<
typename SplitterWorkload, armnn::DataType DataType>
1518 std::unique_ptr<SplitterWorkload>
1529 layerDesc.SetViewOriginCoord(0, 0, 0);
1530 layerDesc.SetViewOriginCoord(1, 0, 1);
1531 layerDesc.SetViewOriginCoord(2, 0, 3);
1543 Connect(input, layer, tensorInfo);
1549 Connect(layer, output0, output0Info, 0, 0);
1550 Connect(layer, output1, output1Info, 1, 0);
1551 Connect(layer, output2, output2Info, 2, 0);
1553 CreateTensorHandles(graph, factory);
1556 auto workload = MakeAndCheckWorkload<SplitterWorkload>(*layer, factory);
1559 CHECK(queueDescriptor.m_Inputs.size() == 1);
1560 CHECK(queueDescriptor.m_Outputs.size() == 3);
1561 CHECK(queueDescriptor.m_ViewOrigins.size() == 3);
1563 CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[0] == 0);
1564 CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[0] == 1);
1565 CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[0] == 3);
1566 CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[1] == 0);
1567 CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[1] == 0);
1568 CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[1] == 0);
1569 CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[2] == 0);
1570 CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[2] == 0);
1571 CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[2] == 0);
1578 template<
typename SplitterWorkload,
typename ConcatWorkload, armnn::DataType DataType>
1579 std::pair<std::unique_ptr<SplitterWorkload>, std::unique_ptr<ConcatWorkload>>
1591 splitterViews.SetViewOriginCoord(0, 0, 0);
1592 splitterViews.SetViewOriginCoord(0, 1, 0);
1593 splitterViews.SetViewOriginCoord(0, 2, 0);
1594 splitterViews.SetViewOriginCoord(0, 3, 0);
1596 splitterViews.SetViewOriginCoord(1, 0, 0);
1597 splitterViews.SetViewOriginCoord(1, 1, 1);
1598 splitterViews.SetViewOriginCoord(1, 2, 0);
1599 splitterViews.SetViewOriginCoord(1, 3, 0);
1606 concatViews.SetViewOriginCoord(0, 0, 0);
1607 concatViews.SetViewOriginCoord(0, 1, 1);
1608 concatViews.SetViewOriginCoord(0, 2, 0);
1609 concatViews.SetViewOriginCoord(0, 3, 0);
1611 concatViews.SetViewOriginCoord(1, 0, 0);
1612 concatViews.SetViewOriginCoord(1, 1, 0);
1613 concatViews.SetViewOriginCoord(1, 2, 0);
1614 concatViews.SetViewOriginCoord(1, 3, 0);
1624 Connect(input, splitter, inputTensorInfo, 0, 0);
1626 Connect(splitter, concat, splitTensorInfo1, 0, 1);
1628 Connect(splitter, concat, splitTensorInfo2, 1, 0);
1630 Connect(concat, output, inputTensorInfo, 0, 0);
1633 CreateTensorHandles(graph, factory);
1636 auto workloadSplitter = MakeAndCheckWorkload<SplitterWorkload>(*splitter, factory);
1637 CHECK(workloadSplitter);
1639 auto workloadConcat = MakeAndCheckWorkload<ConcatWorkload>(*concat, factory);
1640 CHECK(workloadConcat);
1642 return {std::move(workloadSplitter), std::move(workloadConcat)};
1648 template<
typename SplitterWorkload,
typename ActivationWorkload, armnn::DataType DataType>
1650 std::unique_ptr<SplitterWorkload>& wlSplitter,
1651 std::unique_ptr<ActivationWorkload>& wlActiv0_0,
1652 std::unique_ptr<ActivationWorkload>& wlActiv0_1,
1653 std::unique_ptr<ActivationWorkload>& wlActiv1_0,
1654 std::unique_ptr<ActivationWorkload>& wlActiv1_1)
1665 splitterViews.SetViewOriginCoord(0, 0, 0);
1666 splitterViews.SetViewOriginCoord(0, 1, 0);
1667 splitterViews.SetViewOriginCoord(0, 2, 0);
1668 splitterViews.SetViewOriginCoord(0, 3, 0);
1670 splitterViews.SetViewOriginCoord(1, 0, 0);
1671 splitterViews.SetViewOriginCoord(1, 1, 1);
1672 splitterViews.SetViewOriginCoord(1, 2, 0);
1673 splitterViews.SetViewOriginCoord(1, 3, 0);
1690 Connect(input, splitter, inputTensorInfo, 0, 0);
1691 Connect(splitter, activ0_0, splitTensorInfo1, 0, 0);
1692 Connect(splitter, activ0_1, splitTensorInfo1, 0, 0);
1694 Connect(splitter, activ1_0, splitTensorInfo2, 1, 0);
1695 Connect(splitter, activ1_1, splitTensorInfo2, 1, 0);
1697 Connect(activ0_0, output1, splitTensorInfo1, 0, 0);
1698 Connect(activ0_1, output2, splitTensorInfo1, 0, 0);
1699 Connect(activ1_0, output3, splitTensorInfo2, 0, 0);
1700 Connect(activ1_1, output4, splitTensorInfo2, 0, 0);
1702 CreateTensorHandles(graph, factory);
1704 auto workloadSplitter = MakeAndCheckWorkload<SplitterWorkload>(*splitter, factory);
1705 auto workloadActiv0_0 = MakeAndCheckWorkload<ActivationWorkload>(*activ0_0, factory);
1706 auto workloadActiv0_1 = MakeAndCheckWorkload<ActivationWorkload>(*activ0_1, factory);
1707 auto workloadActiv1_0 = MakeAndCheckWorkload<ActivationWorkload>(*activ1_0, factory);
1708 auto workloadActiv1_1 = MakeAndCheckWorkload<ActivationWorkload>(*activ1_1, factory);
1710 wlSplitter = std::move(workloadSplitter);
1711 wlActiv0_0 = std::move(workloadActiv0_0);
1712 wlActiv0_1 = std::move(workloadActiv0_1);
1713 wlActiv1_0 = std::move(workloadActiv1_0);
1714 wlActiv1_1 = std::move(workloadActiv1_1);
1717 template <
typename ResizeWorkload, armnn::DataType DataType>
1725 switch (dataLayout) {
1727 inputShape = { 2, 4, 4, 3 };
1728 outputShape = { 2, 2, 2, 3 };
1732 inputShape = { 2, 3, 4, 4 };
1733 outputShape = { 2, 3, 2, 2 };
1752 Connect(input, layer, inputTensorInfo);
1753 Connect(layer, output, outputTensorInfo);
1754 CreateTensorHandles(graph, factory);
1757 auto workload = MakeAndCheckWorkload<ResizeWorkload>(*layer, factory);
1759 auto queueDescriptor = workload->GetData();
1760 CHECK(queueDescriptor.m_Inputs.size() == 1);
1761 CHECK(queueDescriptor.m_Outputs.size() == 1);
1762 CHECK(queueDescriptor.m_Parameters.m_DataLayout == dataLayout);
1768 template <
typename BatchToSpaceNdWorkload, armnn::DataType DataType>
1782 Connect(input, layer, tensorInfo);
1783 Connect(layer, output, tensorInfo);
1785 CreateTensorHandles(graph, factory);
1788 auto workload = MakeAndCheckWorkload<BatchToSpaceNdWorkload>(*layer, factory);
1791 CHECK(queueDescriptor.m_Inputs.size() == 1);
1792 CHECK(queueDescriptor.m_Outputs.size() == 1);
1797 template <
typename LogSoftmaxWorkload, armnn::DataType DataType>
1806 logSoftmaxDescriptor.
m_Axis = -1;
1817 Connect(input, layer, tensorInfo);
1818 Connect(layer, output, tensorInfo);
1819 CreateTensorHandles(graph, factory);
1822 auto workload = MakeAndCheckWorkload<LogSoftmaxWorkload>(*layer, factory);
1825 CHECK(queueDescriptor.m_Inputs.size() == 1);
1826 CHECK(queueDescriptor.m_Outputs.size() == 1);
1832 template <
typename L2NormalizationWorkload, armnn::DataType DataType>
1854 Connect(input, layer, inputTensorInfo);
1855 Connect(layer, output, outputTensorInfo);
1856 CreateTensorHandles(graph, factory);
1859 auto workload = MakeAndCheckWorkload<L2NormalizationWorkload>(*layer, factory);
1862 CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
1863 CHECK(queueDescriptor.m_Inputs.size() == 1);
1864 CHECK(queueDescriptor.m_Outputs.size() == 1);
1870 template <
typename ReshapeWorkload, armnn::DataType DataType>
1887 Connect(input, layer, inputTensorInfo);
1888 Connect(layer, output, outputTensorInfo);
1889 CreateTensorHandles(graph, factory);
1892 auto workload = MakeAndCheckWorkload<ReshapeWorkload>(*layer, factory);
1895 CHECK(queueDescriptor.m_Inputs.size() == 1);
1896 CHECK(queueDescriptor.m_Outputs.size() == 1);
1902 template <
typename ConvertFp16ToFp32Float32Workload>
1903 std::unique_ptr<ConvertFp16ToFp32Float32Workload> CreateConvertFp16ToFp32WorkloadTest(
1916 Connect(input, layer, inputTensorInfo);
1917 Connect(layer, output, outputTensorInfo);
1918 CreateTensorHandles(graph, factory);
1921 auto workload = MakeAndCheckWorkload<ConvertFp16ToFp32Float32Workload>(*layer, factory);
1924 CHECK(queueDescriptor.m_Inputs.size() == 1);
1925 CHECK(queueDescriptor.m_Outputs.size() == 1);
1931 template <
typename ConvertFp32ToFp16Float16Workload>
1932 std::unique_ptr<ConvertFp32ToFp16Float16Workload> CreateConvertFp32ToFp16WorkloadTest(
1945 Connect(input, layer, inputTensorInfo);
1946 Connect(layer, output, outputTensorInfo);
1947 CreateTensorHandles(graph, factory);
1950 auto workload = MakeAndCheckWorkload<ConvertFp32ToFp16Float16Workload>(*layer, factory);
1953 CHECK(queueDescriptor.m_Inputs.size() == 1);
1954 CHECK(queueDescriptor.m_Outputs.size() == 1);
1960 template <
typename MeanWorkload, armnn::DataType DataType>
1976 Connect(input, layer, inputTensorInfo);
1977 Connect(layer, output, outputTensorInfo);
1978 CreateTensorHandles(graph, factory);
1981 auto workload = MakeAndCheckWorkload<MeanWorkload>(*layer, factory);
1984 CHECK(queueDescriptor.m_Parameters.m_Axis == descriptor.m_Axis);
1985 CHECK(queueDescriptor.m_Parameters.m_KeepDims == descriptor.m_KeepDims);
1986 CHECK(queueDescriptor.m_Inputs.size() == 1);
1987 CHECK(queueDescriptor.m_Outputs.size() == 1);
1993 template<
typename ConcatWorkload, armnn::DataType DataType>
1997 unsigned int concatAxis)
2007 std::vector<armnn::TensorShape> inputShapes{{ 2, 3, 2, 5 }, { 2, 3, 2, 5 }};
2021 Connect(input0, concat, inputTensorInfo, 0, 0);
2023 Connect(input1, concat, inputTensorInfo, 0, 1);
2025 Connect(concat, output, outputTensorInfo, 0, 0);
2028 CreateTensorHandles(graph, factory);
2031 auto workloadConcat = MakeAndCheckWorkload<ConcatWorkload>(*concat, factory);
2032 CHECK(workloadConcat);
2034 return workloadConcat;
2037 template <
typename PreCompiledWorkload, armnn::DataType dataType>
2038 std::pair<armnn::IOptimizedNetworkPtr, std::unique_ptr<PreCompiledWorkload>> CreatePreCompiledWorkloadTest(
2041 bool biasEnabled =
false)
2056 unsigned int weightsLength = weightsTensorInfo.GetNumElements();
2059 std::vector<WeightType> convWeightsData(weightsLength);
2060 for (
unsigned int i = 0; i < weightsLength; ++i)
2062 convWeightsData[i] =
static_cast<WeightType
>(i);
2075 const std::string convLayerName(
"conv layer");
2083 unsigned int biasLength = biasTensorInfo.GetNumElements();
2086 std::vector<BiasType> biasData(biasLength);
2087 std::fill(biasData.begin(), biasData.end(),
static_cast<BiasType
>(0));
2092 convLayer = net->AddConvolution2dLayer(convDesc2d,
2095 convLayerName.c_str());
2100 convLayer = net->AddConvolution2dLayer(convDesc2d,
2103 convLayerName.c_str());
2114 if (dataType == armnn::DataType::QAsymmU8)
2116 inputTensorInfo.SetQuantizationOffset(0);
2117 inputTensorInfo.SetQuantizationScale(0.9f);
2121 if (dataType == armnn::DataType::QAsymmU8)
2123 outputTensorInfo.SetQuantizationOffset(0);
2124 outputTensorInfo.SetQuantizationScale(0.9f);
2135 std::vector<armnn::BackendId> backends = {factory.
GetBackendId()};
2141 CHECK(optimizedNet !=
nullptr);
2145 Layer* preCompiledLayer =
nullptr;
2146 for (
auto& layer : optimisedGraph)
2150 preCompiledLayer = layer;
2153 CHECK(preCompiledLayer !=
nullptr);
2156 CreateTensorHandles(optimisedGraph, factory);
2159 auto workload = MakeAndCheckWorkload<PreCompiledWorkload>(*preCompiledLayer, factory);
2162 CHECK(queueDescriptor.m_Inputs.size() == 1);
2163 CHECK(queueDescriptor.m_Outputs.size() == 1);
2168 return std::make_pair(std::move(optimizedNet), std::move(workload));
2171 template<
typename ConstantWorkload, armnn::DataType DataType>
2181 constant->m_LayerOutput = std::make_unique<ScopedTensorHandle>(outputTensorInfo);
2187 Connect(constant, output, outputTensorInfo, 0, 0);
2190 CreateTensorHandles(graph, factory);
2193 auto workloadConstant = MakeAndCheckWorkload<ConstantWorkload>(*constant, factory);
2194 CHECK(workloadConstant);
2196 return workloadConstant;
2199 template <
typename PreluWorkload>
2209 CHECK(layer !=
nullptr);
2215 CHECK(input !=
nullptr);
2216 CHECK(alpha !=
nullptr);
2217 CHECK(output !=
nullptr);
2223 Connect(input, layer, inputTensorInfo, 0, 0);
2224 Connect(alpha, layer, alphaTensorInfo, 0, 1);
2225 Connect(layer, output, outputTensorInfo, 0, 0);
2226 CreateTensorHandles(graph, factory);
2229 auto workload = MakeAndCheckWorkload<PreluWorkload>(*layer, factory);
2232 CHECK(queueDescriptor.m_Inputs.size() == 2);
2233 CHECK(queueDescriptor.m_Outputs.size() == 1);
2239 template <
typename SpaceToDepthWorkload, armnn::DataType DataType>
2255 Connect(input, layer, inputTensorInfo);
2256 Connect(layer, output, outputTensorInfo);
2258 CreateTensorHandles(graph, factory);
2261 auto workload = MakeAndCheckWorkload<SpaceToDepthWorkload>(*layer, factory);
2264 CHECK(queueDescriptor.m_Inputs.size() == 1);
2265 CHECK(queueDescriptor.m_Outputs.size() == 1);
2270 template <
typename StackWorkload, armnn::DataType DataType>
2276 unsigned int numInputs)
2284 CHECK(stackLayer !=
nullptr);
2287 std::vector<Layer*> inputs;
2288 for (
unsigned int i=0; i<numInputs; ++i)
2291 static_cast<int>(i),
2292 (
"input" + std::to_string(i)).c_str()
2294 CHECK(inputs[i] !=
nullptr);
2297 CHECK(output !=
nullptr);
2300 for (
unsigned int i=0; i<numInputs; ++i)
2302 Connect(inputs[i], stackLayer, inputTensorInfo, 0, i);
2304 Connect(stackLayer, output, outputTensorInfo, 0, 0);
2306 CreateTensorHandles(graph, factory);
2308 auto stackWorkload = MakeAndCheckWorkload<StackWorkload>(*stackLayer, factory);
2310 CHECK(queueDescriptor.m_Inputs.size() == numInputs);
2311 CHECK(queueDescriptor.m_Outputs.size() == 1);
2313 return stackWorkload;
A layer that the constant data can be bound to.
std::shared_ptr< ConstTensorHandle > m_ForgetGateBias
A unique pointer to represent 1D weights tensor with dimensions [num_units].
std::shared_ptr< ConstTensorHandle > m_OutputGateBias
A unique pointer to represent 1D weights tensor with dimensions [num_units].
uint32_t m_PadBottom
Padding bottom value in the height dimension.
bool m_BiasEnabled
Enable/disable bias.
bool m_ProjectionEnabled
Enable/disable the projection layer.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
This layer represents a split operation.
static IRuntimePtr Create(const CreationOptions &options)
virtual const BackendId & GetBackendId() const =0
LstmBasicParameters m_BasicParameters
This layer represents a batch normalization operation.
A ViewsDescriptor for the SplitterLayer.
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
uint32_t m_PadBottom
Padding bottom value in the height dimension.
bool m_BiasEnabled
Enable/disable bias.
std::shared_ptr< ConstTensorHandle > m_CellToForgetWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units].
unsigned int GetWidthIndex() const
float m_K
Kappa value used for the across channel normalization equation.
int m_Axis
Scalar, defaulted to the last index (-1), specifying the dimension the activation will be performed o...
uint32_t m_PadBottom
Padding bottom value in the height dimension.
uint32_t m_PadLeft
Padding left value in the width dimension.
float m_ClippingThresProj
Clipping threshold value for the projection.
A ReshapeDescriptor for the ReshapeLayer.
std::shared_ptr< ConstTensorHandle > m_OutputGateBias
A unique pointer to represent 1D bias tensor with dimensions [num_units] (int32). ...
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
This layer represents a depthwise convolution 2d operation.
std::shared_ptr< ConstTensorHandle > m_LayerOutput
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
bool m_TransposeWeightMatrix
Enable/disable transpose weight matrix.
std::vector< BackendOptions > ModelOptions
uint32_t m_PoolWidth
Pooling width value.
bool m_PeepholeEnabled
Enable/disable peephole.
A Convolution2dDescriptor for the Convolution2dLayer.
float m_Alpha
Alpha value for the normalization equation.
uint32_t m_PadLeft
Padding left value in the width dimension.
This layer converts data type Float 16 to Float 32.
float m_HiddenStateScale
Hidden State quantization scale.
float m_OutputIntermediateScale
Output intermediate quantization scale.
ResizeMethod m_Method
The Interpolation method to use (Bilinear, NearestNeighbor).
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
std::shared_ptr< ConstTensorHandle > m_ForgetLayerNormWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units] (QSymmS16).
float m_Eps
Value to add to the variance. Used to avoid dividing by zero.
This layer represents a SpaceToDepth operation.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
This layer represents a reshape operation.
typename ResolveTypeImpl< DT >::Type ResolveType
std::shared_ptr< ConstTensorHandle > m_Weight
A unique pointer to store Weight values.
std::shared_ptr< ConstTensorHandle > m_InputToOutputWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, inputSize] (QSymmS8)...
This layer represents an activation operation with the specified activation function.
uint32_t m_PadTop
Padding top value in the height dimension.
std::shared_ptr< ConstTensorHandle > m_Mean
A unique pointer to store Mean values.
uint32_t m_PadRight
Padding right value in the width dimension.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Copyright (c) 2021 ARM Limited and Contributors.
std::shared_ptr< ConstTensorHandle > m_InputToCellWeights
A unique pointer to represent 2D weights tensor with dimensions [input_size, num_units].
This layer represents a LSTM operation.
void IgnoreUnused(Ts &&...)
void SetBackendId(const BackendId &id)
A SpaceToDepthDescriptor for the SpaceToDepthLayer.
A BatchToSpaceNdDescriptor for the BatchToSpaceNdLayer.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
std::shared_ptr< ConstTensorHandle > m_InputToCellWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, inputSize] (QSymmS8)...
std::shared_ptr< ConstTensorHandle > m_Beta
A unique pointer to store Beta values.
unsigned int GetHeightIndex() const
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
QLstmOptLayerNormParameters m_LayerNormParameters
NormalizationAlgorithmMethod m_NormMethodType
Normalization method algorithm to use (LocalBrightness, LocalContrast).
This layer represents a elementwiseUnary operation.
A ResizeDescriptor for the ResizeLayer.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
A StackDescriptor for the StackLayer.
std::shared_ptr< ConstTensorHandle > m_CellBias
A unique pointer to represent 1D bias tensor with dimensions [num_units] (int32). ...
TensorShape m_TargetShape
Target shape value.
std::shared_ptr< ConstTensorHandle > m_CellToOutputWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units].
uint32_t m_PoolHeight
Pooling height value.
uint32_t m_PadTop
Padding top value in the height dimension.
std::shared_ptr< ConstTensorHandle > m_InputToForgetWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, inputSize] (QSymmS8)...
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
std::shared_ptr< ConstTensorHandle > m_RecurrentToCellWeights
A unique pointer to represent 2D weights tensor with dimensions [output_size, num_units].
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
A layer user-provided data can be bound to (e.g. inputs, outputs).
std::shared_ptr< ConstTensorHandle > m_CellBias
A unique pointer to represent 1D weights tensor with dimensions [num_units].
bool m_LayerNormEnabled
Enable/disable layer normalization.
This layer represents a fully connected operation.
An LstmDescriptor for the LstmLayer.
uint32_t m_PadRight
Padding right value in the width dimension.
std::shared_ptr< ConstTensorHandle > m_Weight
A unique pointer to store Weight values.
uint32_t m_PadTop
Padding top value in the height dimension.
IOptimizedNetworkPtr Optimize(const INetwork &network, const std::vector< BackendId > &backendPreferences, const IDeviceSpec &deviceSpec, const OptimizerOptions &options=OptimizerOptions(), Optional< std::vector< std::string > &> messages=EmptyOptional())
Create an optimized version of the network.
std::shared_ptr< ConstTensorHandle > m_CellLayerNormWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units] (QSymmS16).
This layer represents a QuantizedLstm operation.
This layer represents a log softmax operation.
std::shared_ptr< ConstTensorHandle > m_ForgetGateBias
A unique pointer to represent 1D bias tensor with dimensions [num_units] (int32). ...
A L2NormalizationDescriptor for the L2NormalizationLayer.
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout...
An OriginsDescriptor for the ConcatLayer.
float m_ProjectionClip
Clipping threshold value for the projection.
A FullyConnectedDescriptor for the FullyConnectedLayer.
bool m_BiasEnabled
Enable/disable bias.
This layer represents a stack operation.
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
float m_InputIntermediateScale
Input intermediate quantization scale.
This layer represents a merge operation.
This layer represents a softmax operation.
uint32_t m_TargetWidth
Target width value.
bool m_PeepholeEnabled
Enable/disable peephole.
This layer represents a BatchToSpaceNd operation.
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
#define ARMNN_ASSERT(COND)
A QLstmDescriptor for the QLstmLayer.
std::shared_ptr< ConstTensorHandle > m_RecurrentToOutputWeights
A unique pointer to represent 2D weights tensor with dimensions [output_size, num_units].
std::shared_ptr< ConstTensorHandle > m_Gamma
A unique pointer to store Gamma values.
GPU Execution: OpenCL: ArmCompute.
static bool IsLayerSupported(const BackendId &backendId, const IConnectableLayer &layer, Optional< DataType > dataType, std::string &outReasonIfUnsupported)
An ActivationDescriptor for the ActivationLayer.
min(a, max(b, input)) ReLu1 & ReLu6.
std::shared_ptr< ConstTensorHandle > m_OutputLayerNormWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units] (QSymmS16).
std::shared_ptr< ConstTensorHandle > m_Variance
A unique pointer to store Variance values.
uint32_t m_TargetHeight
Target height value.
uint32_t m_ActivationFunc
The activation function to use.
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
This layer represents a normalization operation.
This layer represents a pooling 2d operation.
std::shared_ptr< ConstTensorHandle > m_Bias
A unique pointer to store Bias values.
std::shared_ptr< ConstTensorHandle > m_RecurrentToCellWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, outputSize] (QSymmS8)...
float m_ClippingThresCell
Clipping threshold value for the cell state.
This layer converts data type Float 32 to Float 16.
unsigned int m_BlockSize
Scalar specifying the input block size. It must be >= 1.
DataType GetBiasDataType(DataType inputDataType)
void SetAdditionalInfoForObject(const AdditionalInfoObjectPtr &additionalInfo)
float m_ForgetIntermediateScale
Forget intermediate quantization scale.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
This layer represents an addition operation.
QLstmBasicParameters m_BasicParameters
LstmOptPeepholeParameters m_PeepholeParameters
std::shared_ptr< ConstTensorHandle > m_RecurrentToOutputWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, outputSize] (QSymmS8)...
Graph & GetGraphForTesting(IOptimizedNetwork *optNet)
NormalizationAlgorithmChannel m_NormChannelType
Normalization channel algorithm to use (Across, Within).
This layer represents a QLstm operation.
float m_CellClip
Clipping threshold value for the cell state.
float m_A
Alpha upper bound value used by the activation functions. (BoundedReLu, Linear, TanH, Elu).
This layer represents a subtraction operation.
bool m_CifgEnabled
Enable/disable cifg (coupled input & forget gate).
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
A ElementwiseUnaryDescriptor for the ElementwiseUnaryLayer.
std::shared_ptr< ConstTensorHandle > m_InputToForgetWeights
A unique pointer to represent 2D weights tensor with dimensions [input_size, num_units].
PoolingAlgorithm m_PoolType
The pooling algorithm to use (Max. Average, L2).
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
std::shared_ptr< ConstTensorHandle > m_RecurrentToForgetWeights
A unique pointer to represent 2D weights tensor with dimensions [output_size, num_units].
This layer represents a L2 normalization operation.
std::shared_ptr< ConstTensorHandle > m_Bias
A unique pointer to store Bias values.
std::shared_ptr< ConstTensorHandle > m_Weight
A unique pointer to store Weight values.
CPU Execution: NEON: ArmCompute.
bool m_ProjectionEnabled
Enable/disable the projection layer.
OutputShapeRounding m_OutputShapeRounding
The rounding method for the output shape. (Floor, Ceiling).
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
A MeanDescriptor for the MeanLayer.
void SetConstant(const bool IsConstant=true)
Marks the data corresponding to this tensor info as constant.
DataType GetDataType() const
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
This layer represents a convolution 2d operation.
void SetQuantizationOffset(int32_t offset)
void Connect(armnn::IConnectableLayer *from, armnn::IConnectableLayer *to, const armnn::TensorInfo &tensorInfo, unsigned int fromIndex, unsigned int toIndex)
OriginsDescriptor CreateDescriptorForConcatenation(TensorShapeIt first, TensorShapeIt last, unsigned int concatenationDimension)
Convenience template to create an OriginsDescriptor to use when creating a ConcatLayer for performing...
Graph & TopologicalSort()
Sorts layers in topological order and return this.
This layer represents a mean operation.
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
virtual int Connect(IInputSlot &destination)=0
Krichevsky 2012: Local Brightness Normalization.
A Pooling2dDescriptor for the Pooling2dLayer.
A NormalizationDescriptor for the NormalizationLayer.
std::shared_ptr< ConstTensorHandle > m_RecurrentToForgetWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, outputSize] (QSymmS8)...
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
This layer represents a multiplication operation.
virtual void CreateTensorHandles(const TensorHandleFactoryRegistry ®istry, const IWorkloadFactory &factory, const bool IsMemoryManaged=true)
virtual std::unique_ptr< IWorkload > CreateWorkload(const IWorkloadFactory &factory) const =0
float m_CellIntermediateScale
Cell intermediate quantization scale.
static INetworkPtr Create(NetworkOptions networkOptions={})
float m_B
Beta lower bound value used by the activation functions. (BoundedReLu, Linear, TanH).
A SoftmaxDescriptor for the SoftmaxLayer.
float m_Beta
Beta value for the normalization equation.
bool m_CifgEnabled
Enable/disable CIFG (coupled input & forget gate).
uint32_t m_NormSize
Depth radius value.
ActivationFunction m_Function
The activation function to use (Sigmoid, TanH, Linear, ReLu, BoundedReLu, SoftReLu, LeakyReLu, Abs, Sqrt, Square, Elu).
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
A DepthwiseConvolution2dDescriptor for the DepthwiseConvolution2dLayer.
Depthwise Convolution 2D layer workload data.
A BatchNormalizationDescriptor for the BatchNormalizationLayer.
uint32_t m_PadLeft
Padding left value in the width dimension.
std::shared_ptr< T > GetAdditionalInformation() const
This layer represents a resize operation.
std::shared_ptr< ConstTensorHandle > m_InputToOutputWeights
A unique pointer to represent 2D weights tensor with dimensions [input_size, num_units].
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below...
uint32_t m_PadRight
Padding right value in the width dimension.
int32_t m_HiddenStateZeroPoint
Hidden State zero point.
bool m_ConstantWeights
Enable/disable constant weights and biases.