21 #include <boost/test/unit_test.hpp> 25 using namespace armnn;
33 template<
typename Workload>
34 std::unique_ptr<Workload> MakeAndCheckWorkload(
Layer& layer,
38 std::unique_ptr<IWorkload> workload = layer.
CreateWorkload(factory);
39 BOOST_TEST(workload.get() == PolymorphicDowncast<Workload*>(workload.get()),
40 "Cannot convert to derived class");
41 std::string reasonIfUnsupported;
44 return std::unique_ptr<Workload>(
static_cast<Workload*
>(workload.release()));
65 template <
typename ActivationWorkload, armnn::DataType DataType>
73 layerDesc.
m_B = -10.0f;
84 Connect(input, layer, tensorInfo);
85 Connect(layer, output, tensorInfo);
87 CreateTensorHandles(graph, factory);
90 auto workload = MakeAndCheckWorkload<ActivationWorkload>(*layer, factory);
93 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
94 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
95 BOOST_TEST(queueDescriptor.m_Parameters.m_A == 3.5f);
96 BOOST_TEST(queueDescriptor.m_Parameters.m_B == -10.0f);
103 template <
typename WorkloadType,
104 typename DescriptorType,
120 Connect(input1, layer, tensorInfo, 0, 0);
121 Connect(input2, layer, tensorInfo, 0, 1);
122 Connect(layer, output, tensorInfo);
123 CreateTensorHandles(graph, factory);
126 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
128 DescriptorType queueDescriptor = workload->GetData();
129 BOOST_TEST(queueDescriptor.m_Inputs.size() == 2);
130 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
136 template<
typename WorkloadType,
137 typename DescriptorType,
145 auto activationDesc = std::make_shared<ActivationDescriptor>();
146 activationDesc->m_A = 10.0f;
147 activationDesc->m_B = 5.0f;
159 Connect(input1, layer, tensorInfo, 0, 0);
160 Connect(input2, layer, tensorInfo, 0, 1);
161 Connect(layer, output, tensorInfo);
162 CreateTensorHandles(graph, factory);
165 std::shared_ptr<ActivationDescriptor>
168 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
169 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
175 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
177 DescriptorType queueDescriptor = workload->GetData();
180 queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
182 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_A) == 10.0f);
183 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_B) == 5.0f);
188 BOOST_TEST(queueDescriptor.m_Inputs.size() == 2);
189 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
194 template<
typename WorkloadType,
195 typename DescriptorType,
203 auto activationDesc = std::make_shared<ActivationDescriptor>();
204 activationDesc->m_A = 10.0f;
205 activationDesc->m_B = 5.0f;
217 Connect(input1, layer, tensorInfo, 0, 0);
218 Connect(input2, layer, tensorInfo, 0, 1);
219 Connect(layer, output, tensorInfo);
220 CreateTensorHandles(graph, factory);
223 std::shared_ptr<ActivationDescriptor>
226 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
227 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
233 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
235 DescriptorType queueDescriptor = workload->GetData();
236 BOOST_TEST(queueDescriptor.m_Inputs.size() == 2);
237 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
239 queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
241 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
242 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
250 template<
typename WorkloadType,
251 typename DescriptorType,
259 auto activationDesc = std::make_shared<ActivationDescriptor>();
260 activationDesc->m_A = 10.0f;
261 activationDesc->m_B = 5.0f;
273 Connect(input1, layer, tensorInfo, 0, 0);
274 Connect(input2, layer, tensorInfo, 0, 1);
275 Connect(layer, output, tensorInfo);
276 CreateTensorHandles(graph, factory);
279 std::shared_ptr<ActivationDescriptor>
280 activationDescPtr = layer->template GetAdditionalInformation<ActivationDescriptor>();
282 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
283 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
289 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
291 DescriptorType queueDescriptor = workload->GetData();
293 queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
295 BOOST_TEST(queueDescriptor.m_Inputs.size() == 2);
296 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
297 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_A) == 10.0f);
298 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_B) == 5.0f);
306 template <
typename WorkloadType,
307 typename DescriptorType,
320 Connect(input, layer, tensorInfo, 0, 0);
321 Connect(layer, output, tensorInfo, 0, 0);
322 CreateTensorHandles(graph, factory);
324 auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
325 DescriptorType queueDescriptor = workload->GetData();
327 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
328 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
333 template <
typename BatchNormalizationWorkloadType, armnn::DataType DataType>
334 std::unique_ptr<BatchNormalizationWorkloadType> CreateBatchNormalizationWorkloadTest(
341 tensorShape = { 2, 4, 4, 3 };
345 tensorShape = { 2, 3, 4, 4 };
350 layerDesc.
m_Eps = 0.05f;
356 layer->
m_Mean = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
357 layer->
m_Variance = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
358 layer->
m_Beta = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
359 layer->
m_Gamma = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
360 layer->
m_Mean->Allocate();
362 layer->
m_Beta->Allocate();
371 Connect(input, layer, tensorInfo);
372 Connect(layer, output, tensorInfo);
373 CreateTensorHandles(graph, factory);
376 auto workload = MakeAndCheckWorkload<BatchNormalizationWorkloadType>(*layer, factory);
378 BOOST_TEST(queueDescriptor.m_Parameters.m_Eps == 0.05f);
379 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
380 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
382 BOOST_TEST((queueDescriptor.m_Variance->GetTensorInfo() ==
TensorInfo({3},
DataType)));
385 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
391 template <
typename BatchNormalizationWorkloadType, armnn::DataType DataType>
392 std::unique_ptr<BatchNormalizationWorkloadType> CreateBatchNormalizationWithBlobWorkloadTest(
399 tensorShape = { 2, 4, 4, 3 };
403 tensorShape = { 2, 3, 4, 4 };
408 layerDesc.
m_Eps = 0.05f;
414 layer->
m_Mean = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
415 layer->
m_Variance = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
416 layer->
m_Beta = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
417 layer->
m_Gamma = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
418 layer->
m_Mean->Allocate();
420 layer->
m_Beta->Allocate();
423 auto activationDesc = std::make_shared<ActivationDescriptor>();
424 activationDesc->m_A = 10.0f;
425 activationDesc->m_B = 5.0f;
432 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
433 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
444 Connect(input, layer, tensorInfo);
445 Connect(layer, output, tensorInfo);
446 CreateTensorHandles(graph, factory);
449 auto workload = MakeAndCheckWorkload<BatchNormalizationWorkloadType>(*layer, factory);
453 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_A) == 10.0f);
454 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_B) == 5.0f);
459 BOOST_TEST(queueDescriptor.m_Parameters.m_Eps == 0.05f);
460 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
461 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
463 BOOST_TEST((queueDescriptor.m_Variance->GetTensorInfo() ==
TensorInfo({3},
DataType)));
466 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
472 template <
typename Convolution2dWorkload, armnn::DataType DataType>
499 layer->
m_Bias->Allocate();
508 CreateTensorHandles(graph, factory);
511 auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
514 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideX == 2);
515 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideY == 4);
516 BOOST_TEST(queueDescriptor.m_Parameters.m_PadLeft == 3);
517 BOOST_TEST(queueDescriptor.m_Parameters.m_PadRight == 3);
518 BOOST_TEST(queueDescriptor.m_Parameters.m_PadTop == 1);
519 BOOST_TEST(queueDescriptor.m_Parameters.m_PadBottom == 1);
520 BOOST_TEST(queueDescriptor.m_Parameters.m_BiasEnabled);
521 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
523 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
524 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
525 BOOST_TEST((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo(weightShape,
DataType)));
526 BOOST_TEST((queueDescriptor.m_Bias->GetTensorInfo() ==
533 template<
typename Convolution2dWorkload, armnn::DataType DataType>
534 std::unique_ptr<Convolution2dWorkload> CreateConvolution2dFusedActivationWithBlobWorkloadTest(
562 layer->
m_Bias->Allocate();
564 auto activationDesc = std::make_shared<ActivationDescriptor>();
565 activationDesc->m_A = 10.0f;
566 activationDesc->m_B = 5.0f;
574 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
575 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
587 CreateTensorHandles(graph, factory);
590 auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
595 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_A) == 10.0f);
596 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_B) == 5.0f);
601 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideX == 2);
602 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideY == 4);
603 BOOST_TEST(queueDescriptor.m_Parameters.m_PadLeft == 3);
604 BOOST_TEST(queueDescriptor.m_Parameters.m_PadRight == 3);
605 BOOST_TEST(queueDescriptor.m_Parameters.m_PadTop == 1);
606 BOOST_TEST(queueDescriptor.m_Parameters.m_PadBottom == 1);
607 BOOST_TEST(queueDescriptor.m_Parameters.m_BiasEnabled);
608 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
609 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
610 BOOST_TEST((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo(weightShape,
DataType)));
611 BOOST_TEST((queueDescriptor.m_Bias->GetTensorInfo() ==
613 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
619 template <
typename Convolution2dWorkload, armnn::DataType DataType>
620 std::unique_ptr<Convolution2dWorkload> CreateConvolution2dWorkloadFastMathTest(
armnn::IWorkloadFactory& factory,
646 layer->
m_Bias->Allocate();
655 CreateTensorHandles(graph, factory);
658 auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
661 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideX == 1);
662 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideY == 1);
663 BOOST_TEST(queueDescriptor.m_Parameters.m_PadLeft == 0);
664 BOOST_TEST(queueDescriptor.m_Parameters.m_PadRight == 0);
665 BOOST_TEST(queueDescriptor.m_Parameters.m_PadTop == 0);
666 BOOST_TEST(queueDescriptor.m_Parameters.m_PadBottom == 0);
667 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
669 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
670 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
671 BOOST_TEST((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo(weightShape,
DataType)));
677 template <
typename LstmWorkload>
690 unsigned int batchSize = 2;
691 unsigned int inputSize = 2;
692 unsigned int numUnits = 4;
693 unsigned int outputSize = 4;
725 if (layerDesc.m_PeepholeEnabled)
748 armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * (layerDesc.m_CifgEnabled ? 3 : 4) },
750 Connect(input, layer, lstmTensorInfo1, 0, 0);
751 Connect(cellStateIn, layer, lstmTensorInfo2, 0, 1);
752 Connect(outputStateIn, layer, lstmTensorInfo3, 0, 2);
753 Connect(layer, scratchBuffer, lstmTensorInfoScratchBuff, 0, 0);
754 Connect(layer, outputStateOut, lstmTensorInfo3, 1, 0);
755 Connect(layer, cellStateOut, lstmTensorInfo2, 2, 0);
756 Connect(layer, output, lstmTensorInfo3, 3, 0);
758 CreateTensorHandles(graph, factory);
761 auto workload = MakeAndCheckWorkload<LstmWorkload>(*layer, factory);
763 BOOST_TEST(queueDescriptor.m_Parameters.m_ActivationFunc == 4);
764 BOOST_TEST(queueDescriptor.m_Parameters.m_ClippingThresCell == 0.0f);
765 BOOST_TEST(queueDescriptor.m_Parameters.m_ClippingThresProj == 0.0f);
766 BOOST_TEST(queueDescriptor.m_Inputs.size() == 3);
767 BOOST_TEST(queueDescriptor.m_Outputs.size() == 4);
769 BOOST_TEST((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() ==
TensorInfo({ numUnits, inputSize },
771 BOOST_TEST((queueDescriptor.m_OutputGateBias->GetTensorInfo() ==
TensorInfo({ numUnits },
777 template <
typename QuantizedLstmWorkload>
782 unsigned int numBatches = 2;
783 unsigned int inputSize = 2;
784 unsigned int outputSize = 4;
787 float inputOutputScale = 0.0078125f;
788 int32_t inputOutputOffset = 128;
790 float cellStateScale = 0.00048828125f;
791 int32_t cellStateOffset = 0;
793 float weightsScale = 0.00408021f;
794 int32_t weightsOffset = 100;
796 float biasScale = 3.1876640625e-05f;
797 int32_t biasOffset = 0;
816 layer->m_QuantizedLstmParameters.m_InputToInputWeights =
817 std::make_unique<ScopedCpuTensorHandle>(inputWeightsInfo);
818 layer->m_QuantizedLstmParameters.m_InputToForgetWeights =
819 std::make_unique<ScopedCpuTensorHandle>(inputWeightsInfo);
820 layer->m_QuantizedLstmParameters.m_InputToCellWeights =
821 std::make_unique<ScopedCpuTensorHandle>(inputWeightsInfo);
822 layer->m_QuantizedLstmParameters.m_InputToOutputWeights =
823 std::make_unique<ScopedCpuTensorHandle>(inputWeightsInfo);
825 layer->m_QuantizedLstmParameters.m_RecurrentToInputWeights =
826 std::make_unique<ScopedCpuTensorHandle>(recurrentWeightsInfo);
827 layer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights =
828 std::make_unique<ScopedCpuTensorHandle>(recurrentWeightsInfo);
829 layer->m_QuantizedLstmParameters.m_RecurrentToCellWeights =
830 std::make_unique<ScopedCpuTensorHandle>(recurrentWeightsInfo);
831 layer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights =
832 std::make_unique<ScopedCpuTensorHandle>(recurrentWeightsInfo);
834 layer->m_QuantizedLstmParameters.m_InputGateBias = std::make_unique<ScopedCpuTensorHandle>(biasInfo);
835 layer->m_QuantizedLstmParameters.m_ForgetGateBias = std::make_unique<ScopedCpuTensorHandle>(biasInfo);
836 layer->m_QuantizedLstmParameters.m_CellBias = std::make_unique<ScopedCpuTensorHandle>(biasInfo);
837 layer->m_QuantizedLstmParameters.m_OutputGateBias = std::make_unique<ScopedCpuTensorHandle>(biasInfo);
840 layer->m_QuantizedLstmParameters.m_InputToInputWeights->Allocate();
841 layer->m_QuantizedLstmParameters.m_InputToForgetWeights->Allocate();
842 layer->m_QuantizedLstmParameters.m_InputToCellWeights->Allocate();
843 layer->m_QuantizedLstmParameters.m_InputToOutputWeights->Allocate();
845 layer->m_QuantizedLstmParameters.m_RecurrentToInputWeights->Allocate();
846 layer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights->Allocate();
847 layer->m_QuantizedLstmParameters.m_RecurrentToCellWeights->Allocate();
848 layer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights->Allocate();
850 layer->m_QuantizedLstmParameters.m_InputGateBias->Allocate();
851 layer->m_QuantizedLstmParameters.m_ForgetGateBias->Allocate();
852 layer->m_QuantizedLstmParameters.m_CellBias->Allocate();
853 layer->m_QuantizedLstmParameters.m_OutputGateBias->Allocate();
880 Connect(input, layer, inputInfo, 0, 0);
881 Connect(cellStateIn, layer, cellStateInfo, 0, 1);
882 Connect(outputStateIn, layer, outputStateInfo, 0, 2);
884 Connect(layer, cellStateOut, cellStateInfo, 0, 0);
885 Connect(layer, outputStateOut, outputStateInfo, 1, 0);
887 CreateTensorHandles(graph, factory);
890 auto workload = MakeAndCheckWorkload<QuantizedLstmWorkload>(*layer, factory);
894 BOOST_TEST(queueDescriptor.m_Inputs.size() == 3);
895 BOOST_TEST(queueDescriptor.m_Outputs.size() == 2);
898 BOOST_TEST((queueDescriptor.m_InputToInputWeights->GetTensorInfo() == inputWeightsInfo));
899 BOOST_TEST((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == inputWeightsInfo));
900 BOOST_TEST((queueDescriptor.m_InputToCellWeights->GetTensorInfo() == inputWeightsInfo));
901 BOOST_TEST((queueDescriptor.m_InputToOutputWeights->GetTensorInfo() == inputWeightsInfo));
903 BOOST_TEST((queueDescriptor.m_RecurrentToInputWeights->GetTensorInfo() == recurrentWeightsInfo));
904 BOOST_TEST((queueDescriptor.m_RecurrentToForgetWeights->GetTensorInfo() == recurrentWeightsInfo));
905 BOOST_TEST((queueDescriptor.m_RecurrentToCellWeights->GetTensorInfo() == recurrentWeightsInfo));
906 BOOST_TEST((queueDescriptor.m_RecurrentToOutputWeights->GetTensorInfo() == recurrentWeightsInfo));
908 BOOST_TEST((queueDescriptor.m_InputGateBias->GetTensorInfo() == biasInfo));
909 BOOST_TEST((queueDescriptor.m_ForgetGateBias->GetTensorInfo() == biasInfo));
910 BOOST_TEST((queueDescriptor.m_CellBias->GetTensorInfo() == biasInfo));
911 BOOST_TEST((queueDescriptor.m_OutputGateBias->GetTensorInfo() == biasInfo));
916 template <
typename QLstmWorkload>
939 unsigned int numBatches = 2;
940 unsigned int inputSize = 4;
941 unsigned int numUnits = 4;
942 unsigned int outputSize = 4;
945 float inputScale = 0.0078125f;
946 int32_t inputOffset = 0;
949 float outputScale = layerDesc.m_HiddenStateScale;
950 int32_t outputOffset = layerDesc.m_HiddenStateZeroPoint;
952 float cellStateScale = 3.05176e-05f;
953 int32_t cellStateOffset = 0;
955 float weightsScale = 0.00784314f;
956 int32_t weightsOffset = 0;
958 float layerNormScale = 3.05182e-05f;
959 int32_t layerNormOffset = 0;
961 float biasScale = layerNormScale / 1024;
962 int32_t biasOffset = 0;
985 std::make_unique<ScopedCpuTensorHandle>(recurrentWeightsInfo);
987 std::make_unique<ScopedCpuTensorHandle>(recurrentWeightsInfo);
989 std::make_unique<ScopedCpuTensorHandle>(recurrentWeightsInfo);
996 std::make_unique<ScopedCpuTensorHandle>(layerNormWeightsInfo);
998 std::make_unique<ScopedCpuTensorHandle>(layerNormWeightsInfo);
1000 std::make_unique<ScopedCpuTensorHandle>(layerNormWeightsInfo);
1044 Connect(input, layer, inputInfo, 0, 0);
1045 Connect(outputStateIn, layer, outputStateInfo, 0, 1);
1046 Connect(cellStateIn, layer, cellStateInfo, 0, 2);
1048 Connect(layer, outputStateOut, outputStateInfo, 0, 0);
1049 Connect(layer, cellStateOut, cellStateInfo, 1, 0);
1050 Connect(layer, output, outputStateInfo, 2, 0);
1052 CreateTensorHandles(graph, factory);
1055 auto workload = MakeAndCheckWorkload<QLstmWorkload>(*layer, factory);
1057 BOOST_TEST(queueDescriptor.m_Parameters.m_CellClip == 0.0f);
1058 BOOST_TEST(queueDescriptor.m_Parameters.m_ProjectionClip == 0.0f);
1059 BOOST_TEST(queueDescriptor.m_Inputs.size() == 3);
1060 BOOST_TEST(queueDescriptor.m_Outputs.size() == 3);
1062 BOOST_TEST((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == inputWeightsInfo));
1063 BOOST_TEST((queueDescriptor.m_InputToCellWeights->GetTensorInfo() == inputWeightsInfo));
1064 BOOST_TEST((queueDescriptor.m_InputToOutputWeights->GetTensorInfo() == inputWeightsInfo));
1066 BOOST_TEST((queueDescriptor.m_RecurrentToForgetWeights->GetTensorInfo() == recurrentWeightsInfo));
1067 BOOST_TEST((queueDescriptor.m_RecurrentToCellWeights->GetTensorInfo() == recurrentWeightsInfo));
1068 BOOST_TEST((queueDescriptor.m_RecurrentToOutputWeights->GetTensorInfo() == recurrentWeightsInfo));
1070 BOOST_TEST((queueDescriptor.m_ForgetGateBias->GetTensorInfo() == biasInfo));
1071 BOOST_TEST((queueDescriptor.m_CellBias->GetTensorInfo() == biasInfo));
1072 BOOST_TEST((queueDescriptor.m_OutputGateBias->GetTensorInfo() == biasInfo));
1077 template <
typename Convolution2dWorkload, armnn::DataType DataType>
1078 std::unique_ptr<Convolution2dWorkload> CreateDirectConvolution2dWorkloadTest(
armnn::IWorkloadFactory& factory,
1093 float inputsQScale =
DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
1094 float outputQScale =
DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
1097 layer->
m_Bias = std::make_unique<ScopedCpuTensorHandle>
1100 layer->
m_Bias->Allocate();
1109 CreateTensorHandles(graph, factory);
1112 auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory);
1115 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideX == 1);
1116 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideY == 1);
1117 BOOST_TEST(queueDescriptor.m_Parameters.m_PadLeft == 1);
1118 BOOST_TEST(queueDescriptor.m_Parameters.m_PadRight == 1);
1119 BOOST_TEST(queueDescriptor.m_Parameters.m_PadTop == 1);
1120 BOOST_TEST(queueDescriptor.m_Parameters.m_PadBottom == 1);
1121 BOOST_TEST(queueDescriptor.m_Parameters.m_BiasEnabled ==
true);
1123 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1124 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1125 BOOST_TEST((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo({2, 3, 3, 3},
1127 BOOST_TEST((queueDescriptor.m_Bias->GetTensorInfo()
1134 template <
typename DepthwiseConvolution2dFloat32Workload, armnn::DataType DataType>
1135 std::unique_ptr<DepthwiseConvolution2dFloat32Workload> CreateDepthwiseConvolution2dWorkloadTest(
1166 CreateTensorHandles(graph, factory);
1169 auto workload = MakeAndCheckWorkload<DepthwiseConvolution2dFloat32Workload>(*layer, factory);
1172 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideX == 1);
1173 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideY == 1);
1174 BOOST_TEST(queueDescriptor.m_Parameters.m_PadLeft == 1);
1175 BOOST_TEST(queueDescriptor.m_Parameters.m_PadRight == 2);
1176 BOOST_TEST(queueDescriptor.m_Parameters.m_PadTop == 1);
1177 BOOST_TEST(queueDescriptor.m_Parameters.m_PadBottom == 2);
1178 BOOST_TEST(queueDescriptor.m_Parameters.m_BiasEnabled ==
false);
1179 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
1181 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1182 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1183 BOOST_TEST((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo({1, 2, 4, 4},
DataType)));
1189 template <
typename FullyConnectedWorkload, armnn::DataType DataType>
1200 float inputsQScale =
DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
1201 float outputQScale =
DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
1206 layer->
m_Bias->Allocate();
1215 CreateTensorHandles(graph, factory);
1218 auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
1221 BOOST_TEST(queueDescriptor.m_Parameters.m_BiasEnabled ==
true);
1222 BOOST_TEST(queueDescriptor.m_Parameters.m_TransposeWeightMatrix ==
true);
1224 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1225 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1226 BOOST_TEST((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo({7, 20},
DataType, inputsQScale)));
1233 template <
typename FullyConnectedWorkload, armnn::DataType DataType>
1234 std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWithBlobWorkloadTest
1245 float inputsQScale =
DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
1246 float outputQScale =
DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
1251 layer->
m_Bias->Allocate();
1253 auto activationDesc = std::make_shared<ActivationDescriptor>();
1254 activationDesc->m_A = 10.0f;
1255 activationDesc->m_B = 5.0f;
1262 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
1263 BOOST_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
1264 BOOST_ASSERT(static_cast<ActivationFunction>(activationDescPtr->m_Function) ==
1274 CreateTensorHandles(graph, factory);
1277 auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
1284 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_A) == 10.0f);
1285 BOOST_ASSERT(static_cast<float>(queueDescBlobPtr->
m_B) == 5.0f);
1290 BOOST_TEST(queueDescriptor.m_Parameters.m_BiasEnabled ==
true);
1291 BOOST_TEST(queueDescriptor.m_Parameters.m_TransposeWeightMatrix ==
true);
1292 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1293 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1294 BOOST_TEST((queueDescriptor.m_Weight->GetTensorInfo() ==
TensorInfo({7, 20},
DataType, inputsQScale)));
1302 template <
typename NormalizationWorkload, armnn::DataType DataType>
1313 layerDesc.
m_Beta = -1.0f;
1314 layerDesc.
m_K = 0.2f;
1331 Connect(input, layer, inputTensorInfo);
1332 Connect(layer, output, outputTensorInfo);
1333 CreateTensorHandles(graph, factory);
1336 auto workload = MakeAndCheckWorkload<NormalizationWorkload>(*layer, factory);
1341 BOOST_TEST(queueDescriptor.m_Parameters.m_NormSize == 3);
1342 BOOST_TEST(queueDescriptor.m_Parameters.m_Alpha == 0.5f);
1343 BOOST_TEST(queueDescriptor.m_Parameters.m_Beta == -1.0f);
1344 BOOST_TEST(queueDescriptor.m_Parameters.m_K == 0.2f);
1345 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
1347 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1348 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1354 template <
typename Pooling2dWorkload, armnn::DataType DataType>
1385 CreateTensorHandles(graph, factory);
1388 auto workload = MakeAndCheckWorkload<Pooling2dWorkload>(*layer, factory);
1393 BOOST_TEST(queueDescriptor.m_Parameters.m_PoolWidth == 3);
1394 BOOST_TEST(queueDescriptor.m_Parameters.m_PoolHeight == 3);
1395 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideX == 2);
1396 BOOST_TEST(queueDescriptor.m_Parameters.m_StrideY == 3);
1397 BOOST_TEST(queueDescriptor.m_Parameters.m_PadLeft == 2);
1398 BOOST_TEST(queueDescriptor.m_Parameters.m_PadRight == 2);
1399 BOOST_TEST(queueDescriptor.m_Parameters.m_PadTop == 1);
1400 BOOST_TEST(queueDescriptor.m_Parameters.m_PadBottom == 1);
1401 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
1403 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1404 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1410 template <
typename SoftmaxWorkload, armnn::DataType DataType>
1419 softmaxDescriptor.
m_Axis = -1;
1429 if (
DataType == armnn::DataType::QAsymmU8)
1432 tensorInfo.SetQuantizationScale(1.f / 256);
1434 else if (
DataType == armnn::DataType::QAsymmS8)
1436 tensorInfo.SetQuantizationOffset(-128);
1437 tensorInfo.SetQuantizationScale(1.f / 256);
1440 Connect(input, layer, tensorInfo);
1441 Connect(layer, output, tensorInfo);
1442 CreateTensorHandles(graph, factory);
1445 auto workload = MakeAndCheckWorkload<SoftmaxWorkload>(*layer, factory);
1448 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1449 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1455 template<
typename SplitterWorkload, armnn::DataType DataType>
1456 std::unique_ptr<SplitterWorkload>
1467 layerDesc.SetViewOriginCoord(0, 0, 0);
1468 layerDesc.SetViewOriginCoord(1, 0, 1);
1469 layerDesc.SetViewOriginCoord(2, 0, 3);
1481 Connect(input, layer, tensorInfo);
1487 Connect(layer, output0, output0Info, 0, 0);
1488 Connect(layer, output1, output1Info, 1, 0);
1489 Connect(layer, output2, output2Info, 2, 0);
1491 CreateTensorHandles(graph, factory);
1494 auto workload = MakeAndCheckWorkload<SplitterWorkload>(*layer, factory);
1497 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1498 BOOST_TEST(queueDescriptor.m_Outputs.size() == 3);
1499 BOOST_TEST(queueDescriptor.m_ViewOrigins.size() == 3);
1501 BOOST_TEST(queueDescriptor.m_ViewOrigins[0].m_Origin[0] == 0);
1502 BOOST_TEST(queueDescriptor.m_ViewOrigins[1].m_Origin[0] == 1);
1503 BOOST_TEST(queueDescriptor.m_ViewOrigins[2].m_Origin[0] == 3);
1504 BOOST_TEST(queueDescriptor.m_ViewOrigins[0].m_Origin[1] == 0);
1505 BOOST_TEST(queueDescriptor.m_ViewOrigins[1].m_Origin[1] == 0);
1506 BOOST_TEST(queueDescriptor.m_ViewOrigins[2].m_Origin[1] == 0);
1507 BOOST_TEST(queueDescriptor.m_ViewOrigins[0].m_Origin[2] == 0);
1508 BOOST_TEST(queueDescriptor.m_ViewOrigins[1].m_Origin[2] == 0);
1509 BOOST_TEST(queueDescriptor.m_ViewOrigins[2].m_Origin[2] == 0);
1516 template<
typename SplitterWorkload,
typename ConcatWorkload, armnn::DataType DataType>
1517 std::pair<std::unique_ptr<SplitterWorkload>, std::unique_ptr<ConcatWorkload>>
1529 splitterViews.SetViewOriginCoord(0, 0, 0);
1530 splitterViews.SetViewOriginCoord(0, 1, 0);
1531 splitterViews.SetViewOriginCoord(0, 2, 0);
1532 splitterViews.SetViewOriginCoord(0, 3, 0);
1534 splitterViews.SetViewOriginCoord(1, 0, 0);
1535 splitterViews.SetViewOriginCoord(1, 1, 1);
1536 splitterViews.SetViewOriginCoord(1, 2, 0);
1537 splitterViews.SetViewOriginCoord(1, 3, 0);
1540 BOOST_TEST_CHECKPOINT(
"created splitter layer");
1543 concatViews.SetViewOriginCoord(0, 0, 0);
1544 concatViews.SetViewOriginCoord(0, 1, 1);
1545 concatViews.SetViewOriginCoord(0, 2, 0);
1546 concatViews.SetViewOriginCoord(0, 3, 0);
1548 concatViews.SetViewOriginCoord(1, 0, 0);
1549 concatViews.SetViewOriginCoord(1, 1, 0);
1550 concatViews.SetViewOriginCoord(1, 2, 0);
1551 concatViews.SetViewOriginCoord(1, 3, 0);
1554 BOOST_TEST_CHECKPOINT(
"created concat layer");
1559 Connect(input, splitter, inputTensorInfo, 0, 0);
1560 BOOST_TEST_CHECKPOINT(
"connect input to splitter");
1561 Connect(splitter, concat, splitTensorInfo1, 0, 1);
1562 BOOST_TEST_CHECKPOINT(
"connect splitter[0] to concat[1]");
1563 Connect(splitter, concat, splitTensorInfo2, 1, 0);
1564 BOOST_TEST_CHECKPOINT(
"connect splitter[1] to concat[0]");
1565 Connect(concat, output, inputTensorInfo, 0, 0);
1566 BOOST_TEST_CHECKPOINT(
"connect concat to output");
1568 CreateTensorHandles(graph, factory);
1569 BOOST_TEST_CHECKPOINT(
"created tensor handles");
1571 auto workloadSplitter = MakeAndCheckWorkload<SplitterWorkload>(*splitter, factory);
1572 BOOST_TEST_CHECKPOINT(
"created splitter workload");
1573 auto workloadConcat = MakeAndCheckWorkload<ConcatWorkload>(*concat, factory);
1574 BOOST_TEST_CHECKPOINT(
"created concat workload");
1576 return {std::move(workloadSplitter), std::move(workloadConcat)};
1582 template<
typename SplitterWorkload,
typename ActivationWorkload, armnn::DataType DataType>
1584 std::unique_ptr<SplitterWorkload>& wlSplitter,
1585 std::unique_ptr<ActivationWorkload>& wlActiv0_0,
1586 std::unique_ptr<ActivationWorkload>& wlActiv0_1,
1587 std::unique_ptr<ActivationWorkload>& wlActiv1_0,
1588 std::unique_ptr<ActivationWorkload>& wlActiv1_1)
1599 splitterViews.SetViewOriginCoord(0, 0, 0);
1600 splitterViews.SetViewOriginCoord(0, 1, 0);
1601 splitterViews.SetViewOriginCoord(0, 2, 0);
1602 splitterViews.SetViewOriginCoord(0, 3, 0);
1604 splitterViews.SetViewOriginCoord(1, 0, 0);
1605 splitterViews.SetViewOriginCoord(1, 1, 1);
1606 splitterViews.SetViewOriginCoord(1, 2, 0);
1607 splitterViews.SetViewOriginCoord(1, 3, 0);
1624 Connect(input, splitter, inputTensorInfo, 0, 0);
1625 Connect(splitter, activ0_0, splitTensorInfo1, 0, 0);
1626 Connect(splitter, activ0_1, splitTensorInfo1, 0, 0);
1628 Connect(splitter, activ1_0, splitTensorInfo2, 1, 0);
1629 Connect(splitter, activ1_1, splitTensorInfo2, 1, 0);
1631 Connect(activ0_0, output1, splitTensorInfo1, 0, 0);
1632 Connect(activ0_1, output2, splitTensorInfo1, 0, 0);
1633 Connect(activ1_0, output3, splitTensorInfo2, 0, 0);
1634 Connect(activ1_1, output4, splitTensorInfo2, 0, 0);
1636 CreateTensorHandles(graph, factory);
1638 auto workloadSplitter = MakeAndCheckWorkload<SplitterWorkload>(*splitter, factory);
1639 auto workloadActiv0_0 = MakeAndCheckWorkload<ActivationWorkload>(*activ0_0, factory);
1640 auto workloadActiv0_1 = MakeAndCheckWorkload<ActivationWorkload>(*activ0_1, factory);
1641 auto workloadActiv1_0 = MakeAndCheckWorkload<ActivationWorkload>(*activ1_0, factory);
1642 auto workloadActiv1_1 = MakeAndCheckWorkload<ActivationWorkload>(*activ1_1, factory);
1644 wlSplitter = std::move(workloadSplitter);
1645 wlActiv0_0 = std::move(workloadActiv0_0);
1646 wlActiv0_1 = std::move(workloadActiv0_1);
1647 wlActiv1_0 = std::move(workloadActiv1_0);
1648 wlActiv1_1 = std::move(workloadActiv1_1);
1651 template <
typename ResizeWorkload, armnn::DataType DataType>
1659 switch (dataLayout) {
1661 inputShape = { 2, 4, 4, 3 };
1662 outputShape = { 2, 2, 2, 3 };
1666 inputShape = { 2, 3, 4, 4 };
1667 outputShape = { 2, 3, 2, 2 };
1686 Connect(input, layer, inputTensorInfo);
1687 Connect(layer, output, outputTensorInfo);
1688 CreateTensorHandles(graph, factory);
1691 auto workload = MakeAndCheckWorkload<ResizeWorkload>(*layer, factory);
1693 auto queueDescriptor = workload->GetData();
1694 BOOST_CHECK(queueDescriptor.m_Inputs.size() == 1);
1695 BOOST_CHECK(queueDescriptor.m_Outputs.size() == 1);
1696 BOOST_CHECK(queueDescriptor.m_Parameters.m_DataLayout == dataLayout);
1702 template <
typename BatchToSpaceNdWorkload, armnn::DataType DataType>
1716 Connect(input, layer, tensorInfo);
1717 Connect(layer, output, tensorInfo);
1719 CreateTensorHandles(graph, factory);
1722 auto workload = MakeAndCheckWorkload<BatchToSpaceNdWorkload>(*layer, factory);
1725 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1726 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1731 template <
typename LogSoftmaxWorkload, armnn::DataType DataType>
1740 logSoftmaxDescriptor.
m_Axis = -1;
1751 Connect(input, layer, tensorInfo);
1752 Connect(layer, output, tensorInfo);
1753 CreateTensorHandles(graph, factory);
1756 auto workload = MakeAndCheckWorkload<LogSoftmaxWorkload>(*layer, factory);
1759 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1760 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1766 template <
typename L2NormalizationWorkload, armnn::DataType DataType>
1788 Connect(input, layer, inputTensorInfo);
1789 Connect(layer, output, outputTensorInfo);
1790 CreateTensorHandles(graph, factory);
1793 auto workload = MakeAndCheckWorkload<L2NormalizationWorkload>(*layer, factory);
1796 BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
1797 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1798 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1804 template <
typename ReshapeWorkload, armnn::DataType DataType>
1821 Connect(input, layer, inputTensorInfo);
1822 Connect(layer, output, outputTensorInfo);
1823 CreateTensorHandles(graph, factory);
1826 auto workload = MakeAndCheckWorkload<ReshapeWorkload>(*layer, factory);
1829 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1830 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1836 template <
typename ConvertFp16ToFp32Float32Workload>
1837 std::unique_ptr<ConvertFp16ToFp32Float32Workload> CreateConvertFp16ToFp32WorkloadTest(
1850 Connect(input, layer, inputTensorInfo);
1851 Connect(layer, output, outputTensorInfo);
1852 CreateTensorHandles(graph, factory);
1855 auto workload = MakeAndCheckWorkload<ConvertFp16ToFp32Float32Workload>(*layer, factory);
1858 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1859 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1865 template <
typename ConvertFp32ToFp16Float16Workload>
1866 std::unique_ptr<ConvertFp32ToFp16Float16Workload> CreateConvertFp32ToFp16WorkloadTest(
1879 Connect(input, layer, inputTensorInfo);
1880 Connect(layer, output, outputTensorInfo);
1881 CreateTensorHandles(graph, factory);
1884 auto workload = MakeAndCheckWorkload<ConvertFp32ToFp16Float16Workload>(*layer, factory);
1887 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1888 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1894 template <
typename MeanWorkload, armnn::DataType DataType>
1910 Connect(input, layer, inputTensorInfo);
1911 Connect(layer, output, outputTensorInfo);
1912 CreateTensorHandles(graph, factory);
1915 auto workload = MakeAndCheckWorkload<MeanWorkload>(*layer, factory);
1918 BOOST_TEST(queueDescriptor.m_Parameters.m_Axis == descriptor.m_Axis);
1919 BOOST_TEST(queueDescriptor.m_Parameters.m_KeepDims == descriptor.m_KeepDims);
1920 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
1921 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
1927 template<
typename ConcatWorkload, armnn::DataType DataType>
1931 unsigned int concatAxis)
1941 std::vector<armnn::TensorShape> inputShapes{{ 2, 3, 2, 5 }, { 2, 3, 2, 5 }};
1948 BOOST_TEST_CHECKPOINT(
"created concat layer");
1953 Connect(input0, concat, inputTensorInfo, 0, 0);
1954 BOOST_TEST_CHECKPOINT(
"connect input0 to concat");
1955 Connect(input1, concat, inputTensorInfo, 0, 1);
1956 BOOST_TEST_CHECKPOINT(
"connect input1 to concat");
1957 Connect(concat, output, outputTensorInfo, 0, 0);
1958 BOOST_TEST_CHECKPOINT(
"connect concat to output");
1960 CreateTensorHandles(graph, factory);
1961 BOOST_TEST_CHECKPOINT(
"created tensor handles");
1963 auto workloadConcat = MakeAndCheckWorkload<ConcatWorkload>(*concat, factory);
1964 BOOST_TEST_CHECKPOINT(
"created concat workload");
1966 return workloadConcat;
1969 template <
typename PreCompiledWorkload, armnn::DataType dataType>
1970 std::pair<armnn::IOptimizedNetworkPtr, std::unique_ptr<PreCompiledWorkload>> CreatePreCompiledWorkloadTest(
1973 bool biasEnabled =
false)
1982 BOOST_TEST(inputLayer);
1988 unsigned int weightsLength = weightsTensorInfo.GetNumElements();
1991 std::vector<WeightType> convWeightsData(weightsLength);
1992 for (
unsigned int i = 0; i < weightsLength; ++i)
1994 convWeightsData[i] =
static_cast<WeightType
>(i);
2007 const std::string convLayerName(
"conv layer");
2015 unsigned int biasLength = biasTensorInfo.GetNumElements();
2018 std::vector<BiasType> biasData(biasLength);
2019 std::fill(biasData.begin(), biasData.end(),
static_cast<BiasType
>(0));
2024 convLayer = net->AddConvolution2dLayer(convDesc2d,
2027 convLayerName.c_str());
2032 convLayer = net->AddConvolution2dLayer(convDesc2d,
2035 convLayerName.c_str());
2038 BOOST_TEST(convLayer);
2042 BOOST_TEST(outputLayer);
2046 if (dataType == armnn::DataType::QAsymmU8)
2048 inputTensorInfo.SetQuantizationOffset(0);
2049 inputTensorInfo.SetQuantizationScale(0.9f);
2053 if (dataType == armnn::DataType::QAsymmU8)
2055 outputTensorInfo.SetQuantizationOffset(0);
2056 outputTensorInfo.SetQuantizationScale(0.9f);
2067 std::vector<armnn::BackendId> backends = {factory.
GetBackendId()};
2073 BOOST_CHECK(optimizedNet !=
nullptr);
2077 Layer* preCompiledLayer =
nullptr;
2078 for (
auto& layer : optimisedGraph)
2082 preCompiledLayer = layer;
2085 BOOST_CHECK(preCompiledLayer !=
nullptr);
2088 CreateTensorHandles(optimisedGraph, factory);
2091 auto workload = MakeAndCheckWorkload<PreCompiledWorkload>(*preCompiledLayer, factory);
2094 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
2095 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
2100 return std::make_pair(std::move(optimizedNet), std::move(workload));
2103 template<
typename ConstantWorkload, armnn::DataType DataType>
2111 constant->
m_LayerOutput = std::make_unique<ScopedCpuTensorHandle>(outputTensorInfo);
2112 BOOST_TEST_CHECKPOINT(
"created constant layer");
2117 Connect(constant, output, outputTensorInfo, 0, 0);
2118 BOOST_TEST_CHECKPOINT(
"connect constant to output");
2120 CreateTensorHandles(graph, factory);
2121 BOOST_TEST_CHECKPOINT(
"created tensor handles");
2123 auto workloadConstant = MakeAndCheckWorkload<ConstantWorkload>(*constant, factory);
2124 BOOST_TEST_CHECKPOINT(
"created Constant workload");
2126 return workloadConstant;
2129 template <
typename PreluWorkload>
2139 BOOST_CHECK(layer !=
nullptr);
2145 BOOST_CHECK(input !=
nullptr);
2146 BOOST_CHECK(alpha !=
nullptr);
2147 BOOST_CHECK(output !=
nullptr);
2153 Connect(input, layer, inputTensorInfo, 0, 0);
2154 Connect(alpha, layer, alphaTensorInfo, 0, 1);
2155 Connect(layer, output, outputTensorInfo, 0, 0);
2156 CreateTensorHandles(graph, factory);
2159 auto workload = MakeAndCheckWorkload<PreluWorkload>(*layer, factory);
2162 BOOST_TEST(queueDescriptor.m_Inputs.size() == 2);
2163 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
2169 template <
typename SpaceToDepthWorkload, armnn::DataType DataType>
2185 Connect(input, layer, inputTensorInfo);
2186 Connect(layer, output, outputTensorInfo);
2188 CreateTensorHandles(graph, factory);
2191 auto workload = MakeAndCheckWorkload<SpaceToDepthWorkload>(*layer, factory);
2194 BOOST_TEST(queueDescriptor.m_Inputs.size() == 1);
2195 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
2200 template <
typename StackWorkload, armnn::DataType DataType>
2206 unsigned int numInputs)
2214 BOOST_CHECK(stackLayer !=
nullptr);
2217 std::vector<Layer*> inputs;
2218 for (
unsigned int i=0; i<numInputs; ++i)
2221 static_cast<int>(i),
2222 (
"input" + std::to_string(i)).c_str()
2224 BOOST_CHECK(inputs[i] !=
nullptr);
2227 BOOST_CHECK(output !=
nullptr);
2230 for (
unsigned int i=0; i<numInputs; ++i)
2232 Connect(inputs[i], stackLayer, inputTensorInfo, 0, i);
2234 Connect(stackLayer, output, outputTensorInfo, 0, 0);
2236 CreateTensorHandles(graph, factory);
2238 auto stackWorkload = MakeAndCheckWorkload<StackWorkload>(*stackLayer, factory);
2240 BOOST_TEST(queueDescriptor.m_Inputs.size() == numInputs);
2241 BOOST_TEST(queueDescriptor.m_Outputs.size() == 1);
2243 return stackWorkload;
A layer that the constant data can be bound to.
std::unique_ptr< ScopedCpuTensorHandle > m_ForgetGateBias
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.
std::unique_ptr< ScopedCpuTensorHandle > m_InputToOutputWeights
A unique pointer to represent 2D weights tensor with dimensions [input_size, num_units].
std::unique_ptr< ScopedCpuTensorHandle > m_RecurrentToCellWeights
A unique pointer to represent 2D weights tensor with dimensions [output_size, num_units].
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.
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.
std::unique_ptr< ScopedCpuTensorHandle > m_Weight
A unique pointer to store Weight values.
float m_ClippingThresProj
Clipping threshold value for the projection.
A ReshapeDescriptor for the ReshapeLayer.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
std::unique_ptr< ScopedCpuTensorHandle > m_OutputGateBias
A unique pointer to represent 1D bias tensor with dimensions [num_units] (int32). ...
This layer represents a depthwise convolution 2d operation.
std::unique_ptr< ScopedCpuTensorHandle > m_CellLayerNormWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units] (QSymmS16).
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::unique_ptr< ScopedCpuTensorHandle > m_Bias
A unique pointer to store Bias values.
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.
std::unique_ptr< ScopedCpuTensorHandle > m_RecurrentToForgetWeights
A unique pointer to represent 2D weights tensor with dimensions [output_size, num_units].
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
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).
std::unique_ptr< ScopedCpuTensorHandle > m_Gamma
A unique pointer to store Gamma values.
std::unique_ptr< ScopedCpuTensorHandle > m_OutputGateBias
A unique pointer to represent 1D weights tensor with dimensions [num_units].
This layer represents a reshape operation.
std::unique_ptr< ScopedCpuTensorHandle > m_Variance
A unique pointer to store Variance values.
std::unique_ptr< ScopedCpuTensorHandle > m_InputToForgetWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, inputSize] (QSymmS8)...
std::unique_ptr< ScopedCpuTensorHandle > m_CellBias
A unique pointer to represent 1D bias tensor with dimensions [num_units] (int32). ...
typename ResolveTypeImpl< DT >::Type ResolveType
This layer represents an activation operation with the specified activation function.
uint32_t m_PadTop
Padding top value in the height dimension.
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.
This layer represents a LSTM operation.
void IgnoreUnused(Ts &&...)
std::unique_ptr< ScopedCpuTensorHandle > m_InputToOutputWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, inputSize] (QSymmS8)...
void SetBackendId(const BackendId &id)
A SpaceToDepthDescriptor for the SpaceToDepthLayer.
A BatchToSpaceNdDescriptor for the BatchToSpaceNdLayer.
std::unique_ptr< ScopedCpuTensorHandle > m_OutputLayerNormWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units] (QSymmS16).
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
std::unique_ptr< ScopedCpuTensorHandle > m_CellBias
A unique pointer to represent 1D weights tensor with dimensions [num_units].
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.
std::unique_ptr< ScopedCpuTensorHandle > m_Beta
A unique pointer to store Beta values.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
A StackDescriptor for the StackLayer.
TensorShape m_TargetShape
Target shape value.
std::unique_ptr< ScopedCpuTensorHandle > m_RecurrentToForgetWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, outputSize] (QSymmS8)...
uint32_t m_PoolHeight
Pooling height value.
uint32_t m_PadTop
Padding top value in the height dimension.
std::unique_ptr< ScopedCpuTensorHandle > m_CellToForgetWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units].
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
std::unique_ptr< ScopedCpuTensorHandle > m_LayerOutput
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).
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.
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.
This layer represents a QuantizedLstm operation.
This layer represents a log softmax operation.
std::unique_ptr< ScopedCpuTensorHandle > m_Mean
A unique pointer to store Mean values.
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.
std::unique_ptr< ScopedCpuTensorHandle > m_Weight
A unique pointer to store Weight values.
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
A QLstmDescriptor for the QLstmLayer.
std::unique_ptr< ScopedCpuTensorHandle > m_ForgetLayerNormWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units] (QSymmS16).
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.
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.
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)
std::unique_ptr< ScopedCpuTensorHandle > m_InputToCellWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, inputSize] (QSymmS8)...
float m_ForgetIntermediateScale
Forget intermediate quantization scale.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
This layer represents an addition operation.
std::unique_ptr< ScopedCpuTensorHandle > m_RecurrentToOutputWeights
A unique pointer to represent 2D weights tensor with dimensions [output_size, num_units].
QLstmBasicParameters m_BasicParameters
LstmOptPeepholeParameters m_PeepholeParameters
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).
std::unique_ptr< ScopedCpuTensorHandle > m_InputToCellWeights
A unique pointer to represent 2D weights tensor with dimensions [input_size, num_units].
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
std::unique_ptr< ScopedCpuTensorHandle > m_ForgetGateBias
A unique pointer to represent 1D bias tensor with dimensions [num_units] (int32). ...
A ElementwiseUnaryDescriptor for the ElementwiseUnaryLayer.
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.
This layer represents a L2 normalization operation.
std::unique_ptr< ScopedCpuTensorHandle > m_RecurrentToCellWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, outputSize] (QSymmS8)...
CPU Execution: NEON: ArmCompute.
bool m_ProjectionEnabled
Enable/disable the projection layer.
OutputShapeRounding m_OutputShapeRounding
The rounding method for the output shape. (Floor, Ceiling).
std::unique_ptr< ScopedCpuTensorHandle > m_Bias
A unique pointer to store Bias values.
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
A MeanDescriptor for the MeanLayer.
std::unique_ptr< ScopedCpuTensorHandle > m_CellToOutputWeights
A unique pointer to represent 1D weights tensor with dimensions [num_units].
DataType GetDataType() const
std::unique_ptr< ScopedCpuTensorHandle > m_RecurrentToOutputWeights
A unique pointer to represent 2D weights tensor with dimensions [num_units, outputSize] (QSymmS8)...
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.
std::unique_ptr< ScopedCpuTensorHandle > m_Weight
A unique pointer to store Weight values.
A Pooling2dDescriptor for the Pooling2dLayer.
A NormalizationDescriptor for the NormalizationLayer.
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={})
std::unique_ptr< ScopedCpuTensorHandle > m_InputToForgetWeights
A unique pointer to represent 2D weights tensor with dimensions [input_size, num_units].
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.
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.
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.