15 #include <boost/test/unit_test.hpp> 17 #include <unordered_map> 19 using namespace armnn;
25 struct ExpectedSubgraphSize
27 size_t m_NumInputSlots = 0;
28 size_t m_NumOutputSlots = 0;
29 size_t m_NumLayers = 0;
33 using LayerNameToLayerMap = std::unordered_map<std::string, Layer*>;
37 template <
typename SlotType>
38 SlotType* ConvertReferenceTypeToPointerType(
const SlotType& input)
40 return const_cast<SlotType*
>(&input);
45 template <
typename SlotType>
46 std::vector<SlotType*> ConvertReferenceTypeToPointerType(
const std::vector<SlotType>& input)
48 std::vector<SlotType*> output;
49 std::transform(input.begin(),
51 std::back_inserter(output),
52 [](
const SlotType& inputItem)
54 return ConvertReferenceTypeToPointerType(inputItem);
62 const std::string& layerName,
67 BOOST_TEST(inputLayer);
74 const std::string& layerName)
77 BOOST_TEST(outputLayer);
83 LayerNameToLayerMap& layersInGraph,
85 const std::string& layerName,
91 BOOST_TEST(convLayer);
94 layersInGraph.insert(std::make_pair(convLayer->
GetName(), convLayer));
100 LayerNameToLayerMap& layersInGraph,
102 const std::string& layerName,
106 BOOST_TEST(poolingLayer);
108 layersInGraph.insert(std::make_pair(poolingLayer->
GetName(), poolingLayer));
114 LayerNameToLayerMap& layersInGraph,
115 const std::string& layerName,
119 BOOST_TEST(additionLayer);
121 layersInGraph.insert(std::make_pair(additionLayer->
GetName(), additionLayer));
122 return additionLayer;
127 const ExpectedSubgraphSize& expectedSubstitutableSubgraphSize,
128 const ExpectedSubgraphSize& expectedReplacementSubgraphSize,
143 BOOST_TEST(substitutableSubgraphInputSlots.size() == expectedSubstitutableSubgraphSize.m_NumInputSlots);
144 BOOST_TEST(substitutableSubgraphOutputSlots.size() == expectedSubstitutableSubgraphSize.m_NumOutputSlots);
145 BOOST_TEST(substitutableSubgraphLayers.size() == expectedSubstitutableSubgraphSize.m_NumLayers);
147 BOOST_TEST(
AreEqual(substitutableSubgraphInputSlots, expectedSubstitutableInputSlots));
148 BOOST_TEST(
AreEqual(substitutableSubgraphOutputSlots, expectedSubstitutableOutputSlots));
149 BOOST_TEST(
AreEqual(substitutableSubgraphLayers, expectedSubstitutableLayers));
151 BOOST_TEST(replacementSubgraphInputSlots.size() == expectedReplacementSubgraphSize.m_NumInputSlots);
152 BOOST_TEST(replacementSubgraphOutputSlots.size() == expectedReplacementSubgraphSize.m_NumOutputSlots);
153 BOOST_TEST(replacementSubgraphLayers.size() == expectedReplacementSubgraphSize.m_NumLayers);
155 BOOST_TEST(!
AreEqual(replacementSubgraphInputSlots, expectedSubstitutableInputSlots));
156 BOOST_TEST(!
AreEqual(replacementSubgraphOutputSlots, expectedSubstitutableOutputSlots));
157 BOOST_TEST(!
AreEqual(replacementSubgraphLayers, expectedSubstitutableLayers));
159 BOOST_TEST(std::all_of(replacementSubgraphLayers.begin(),
160 replacementSubgraphLayers.end(),
161 [](
const Layer* layer)
168 void CheckFailedSubgraph(
const SubgraphView& failedSubgraph,
169 const ExpectedSubgraphSize& expectedFailedSubgraphSize,
178 BOOST_TEST(failedSubgraphInputSlots.size() == expectedFailedSubgraphSize.m_NumInputSlots);
179 BOOST_TEST(failedSubgraphOutputSlots.size() == expectedFailedSubgraphSize.m_NumOutputSlots);
180 BOOST_TEST(failedSubgraphLayers.size() == expectedFailedSubgraphSize.m_NumLayers);
182 BOOST_TEST(
AreEqual(failedSubgraphInputSlots, expectedFailedInputSlots));
183 BOOST_TEST(
AreEqual(failedSubgraphOutputSlots, expectedFailedOutputSlots));
184 BOOST_TEST(
AreEqual(failedSubgraphLayers, expectedFailedLayers));
188 void CheckUntouchedSubgraph(
const SubgraphView& untouchedSubgraph,
189 const ExpectedSubgraphSize& expectedUntouchedSubgraphSize,
198 BOOST_TEST(untouchedSubgraphInputSlots.size() == expectedUntouchedSubgraphSize.m_NumInputSlots);
199 BOOST_TEST(untouchedSubgraphOutputSlots.size() == expectedUntouchedSubgraphSize.m_NumOutputSlots);
200 BOOST_TEST(untouchedSubgraphLayers.size() == expectedUntouchedSubgraphSize.m_NumLayers);
202 BOOST_TEST(
AreEqual(untouchedSubgraphInputSlots, expectedUntouchedInputSlots));
203 BOOST_TEST(
AreEqual(untouchedSubgraphOutputSlots, expectedUntouchedOutputSlots));
204 BOOST_TEST(
AreEqual(untouchedSubgraphLayers, expectedUntouchedLayers));
215 poolingDescriptor.m_PoolWidth = 2;
216 poolingDescriptor.m_PoolHeight = 2;
217 poolingDescriptor.m_StrideX = 2;
218 poolingDescriptor.m_StrideY = 2;
219 poolingDescriptor.m_PadLeft = 1;
220 poolingDescriptor.m_PadRight = 1;
221 poolingDescriptor.m_PadTop = 1;
222 poolingDescriptor.m_PadBottom = 1;
227 Layer*
const inputLayer = AddInputLayer(graph,
"input layer", inputInfo);
228 Pooling2dLayer*
const poolingLayer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
229 "pooling layer", outputInfo);
230 Layer*
const outputLayer = AddOutputLayer(graph,
"output layer");
250 poolingDescriptor.m_PoolWidth = 2;
251 poolingDescriptor.m_PoolHeight = 2;
252 poolingDescriptor.m_StrideX = 2;
253 poolingDescriptor.m_StrideY = 2;
254 poolingDescriptor.m_PadLeft = 1;
255 poolingDescriptor.m_PadRight = 1;
256 poolingDescriptor.m_PadTop = 1;
257 poolingDescriptor.m_PadBottom = 1;
262 Layer*
const inputLayer = AddInputLayer(graph,
"input layer", inputInfo);
263 Pooling2dLayer*
const pooling1Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
264 "pooling1 layer", outputInfo);
265 Pooling2dLayer*
const pooling2Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
266 "pooling2 layer", outputInfo);
267 Pooling2dLayer*
const pooling3Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
268 "pooling3 layer", outputInfo);
269 Layer*
const outputLayer = AddOutputLayer(graph,
"output layer");
294 convolutionDescriptor.m_StrideX = 1;
295 convolutionDescriptor.m_StrideY = 1;
296 convolutionDescriptor.m_BiasEnabled =
true;
300 Layer*
const inputLayer = AddInputLayer(graph,
"input layer", inputInfo);
301 Convolution2dLayer*
const convLayer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
302 "conv layer", weightInfo, biasInfo, outputInfo);
303 Layer*
const outputLayer = AddOutputLayer(graph,
"output layer");
325 convolutionDescriptor.m_StrideY = 1;
326 convolutionDescriptor.m_BiasEnabled =
true;
330 Layer*
const inputLayer = AddInputLayer(graph,
"input layer", inputInfo);
331 Convolution2dLayer*
const conv1Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
332 "conv1 layer", weightInfo, biasInfo, outputInfo);
333 Convolution2dLayer*
const conv2Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
334 "conv2 layer", weightInfo, biasInfo, outputInfo);
335 Convolution2dLayer*
const conv3Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
336 "conv3 layer", weightInfo, biasInfo, outputInfo);
337 Convolution2dLayer*
const conv4Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
338 "conv4 layer", weightInfo, biasInfo, outputInfo);
339 Convolution2dLayer*
const conv5Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
340 "conv5 layer", weightInfo, biasInfo, outputInfo);
341 Layer*
const outputLayer = AddOutputLayer(graph,
"output layer");
372 convolutionDescriptor.m_StrideY = 1;
373 convolutionDescriptor.m_BiasEnabled =
true;
390 Layer*
const inputLayer = AddInputLayer(graph,
"input layer", inputInfo);
391 Convolution2dLayer*
const conv1Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
392 "conv1 layer", weightInfo, biasInfo, outputInfo);
393 Pooling2dLayer*
const pooling1Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
394 "pooling1 layer", outputInfo);
395 Pooling2dLayer*
const pooling2Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
396 "pooling2 layer", outputInfo);
397 Convolution2dLayer*
const conv2Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
398 "conv2 layer", weightInfo, biasInfo, outputInfo);
399 Pooling2dLayer*
const pooling3Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
400 "pooling3 layer", outputInfo);
401 Layer*
const outputLayer = AddOutputLayer(graph,
"output layer");
431 convolutionDescriptor.m_StrideY = 1;
432 convolutionDescriptor.m_BiasEnabled =
true;
436 Layer*
const inputLayer = AddInputLayer(graph,
"input layer", inputInfo);
437 Convolution2dLayer*
const convLayer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
438 "conv layer unoptimizable", weightInfo, biasInfo,
440 Layer*
const outputLayer = AddOutputLayer(graph,
"output layer");
462 convolutionDescriptor.m_StrideY = 1;
463 convolutionDescriptor.m_BiasEnabled =
true;
467 Layer*
const inputLayer = AddInputLayer(graph,
"input layer", inputInfo);
468 Convolution2dLayer*
const conv1Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
469 "conv1 layer", weightInfo, biasInfo, outputInfo);
470 Convolution2dLayer*
const conv2Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
471 "conv2 layer unoptimizable", weightInfo, biasInfo,
473 Convolution2dLayer*
const conv3Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
474 "conv3 layer", weightInfo, biasInfo, outputInfo);
475 Convolution2dLayer*
const conv4Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
476 "conv4 layer unoptimizable", weightInfo, biasInfo,
478 Convolution2dLayer*
const conv5Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
479 "conv5 layer", weightInfo, biasInfo, outputInfo);
480 Layer*
const outputLayer = AddOutputLayer(graph,
"output layer");
511 convolutionDescriptor.m_StrideY = 1;
512 convolutionDescriptor.m_BiasEnabled =
true;
516 Layer*
const input1Layer = AddInputLayer(graph,
"input1 layer", inputInfo, 0);
517 Layer*
const input2Layer = AddInputLayer(graph,
"input2 layer", inputInfo, 1);
518 Convolution2dLayer*
const conv1Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
519 "conv1 layer", weightInfo, biasInfo, outputInfo);
520 Convolution2dLayer*
const conv2Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
521 "conv2 layer unoptimizable", weightInfo, biasInfo,
523 Convolution2dLayer*
const conv3Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
524 "conv3 layer", weightInfo, biasInfo, outputInfo);
525 AdditionLayer*
const addLayer = AddAdditionaLayer(graph, layersInGraph,
"add layer", outputInfo);
526 Layer*
const outputLayer = AddOutputLayer(graph,
"output layer");
547 void FullyUnsupporteSubgraphTestImpl1()
550 LayerNameToLayerMap layersInGraph;
554 BOOST_TEST((subgraphPtr !=
nullptr));
560 BOOST_TEST(subgraphInputSlots.size() == 1);
561 BOOST_TEST(subgraphOutputSlots.size() == 1);
562 BOOST_TEST(subgraphLayers.size() == 1);
564 BOOST_TEST(
Contains(layersInGraph,
"pooling layer"));
569 BOOST_TEST((backendObjPtr !=
nullptr));
575 BOOST_CHECK_NO_THROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));
595 BOOST_TEST(failedSubgraphs.size() == 1);
597 CheckFailedSubgraph(failedSubgraphs.at(0),
598 { subgraphInputSlots.size(), subgraphOutputSlots.size(), subgraphLayers.size() },
611 void FullyUnsupporteSubgraphTestImpl2()
614 LayerNameToLayerMap layersInGraph;
618 BOOST_TEST((subgraphPtr !=
nullptr));
624 BOOST_TEST(subgraphInputSlots.size() == 1);
625 BOOST_TEST(subgraphOutputSlots.size() == 1);
626 BOOST_TEST(subgraphLayers.size() == 3);
628 BOOST_TEST(
Contains(layersInGraph,
"pooling1 layer"));
629 BOOST_TEST(
Contains(layersInGraph,
"pooling2 layer"));
630 BOOST_TEST(
Contains(layersInGraph,
"pooling3 layer"));
635 BOOST_TEST((backendObjPtr !=
nullptr));
641 BOOST_CHECK_NO_THROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));
661 BOOST_TEST(failedSubgraphs.size() == 1);
663 std::vector<Layer*> expectedFailedLayers{ layersInGraph.at(
"pooling1 layer"),
664 layersInGraph.at(
"pooling2 layer"),
665 layersInGraph.at(
"pooling3 layer") };
667 const SubgraphView& failedSubgraph = failedSubgraphs.at(0);
669 CheckFailedSubgraph(failedSubgraph,
670 { subgraphInputSlots.size(), subgraphOutputSlots.size(), subgraphLayers.size() },
677 BOOST_TEST(failedSubgraphLayers.front() + 0, expectedFailedLayers.at(0));
678 BOOST_TEST(failedSubgraphLayers.front() + 1, expectedFailedLayers.at(1));
679 BOOST_TEST(failedSubgraphLayers.front() + 2, expectedFailedLayers.at(2));
689 void FullyOptimizableSubgraphTestImpl1()
692 LayerNameToLayerMap layersInGraph;
696 BOOST_TEST((subgraphPtr !=
nullptr));
702 BOOST_TEST(subgraphInputSlots.size() == 1);
703 BOOST_TEST(subgraphOutputSlots.size() == 1);
704 BOOST_TEST(subgraphLayers.size() == 1);
706 BOOST_TEST(
Contains(layersInGraph,
"conv layer"));
711 BOOST_TEST((backendObjPtr !=
nullptr));
717 BOOST_CHECK_NO_THROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));
731 BOOST_TEST(substitutions.size() == 1);
733 CheckSubstitution(substitutions.at(0),
734 { subgraphInputSlots.size(), subgraphOutputSlots.size(), subgraphLayers.size() },
735 { subgraphInputSlots.size(), subgraphOutputSlots.size(), 1 },
754 void FullyOptimizableSubgraphTestImpl2()
757 LayerNameToLayerMap layersInGraph;
761 BOOST_TEST((subgraphPtr !=
nullptr));
767 BOOST_TEST(subgraphPtr->GetInputSlots().size() == 1);
768 BOOST_TEST(subgraphPtr->GetOutputSlots().size() == 1);
769 BOOST_TEST(subgraphPtr->GetLayers().size() == 5);
771 BOOST_TEST(
Contains(layersInGraph,
"conv1 layer"));
772 BOOST_TEST(
Contains(layersInGraph,
"conv2 layer"));
773 BOOST_TEST(
Contains(layersInGraph,
"conv3 layer"));
774 BOOST_TEST(
Contains(layersInGraph,
"conv4 layer"));
775 BOOST_TEST(
Contains(layersInGraph,
"conv5 layer"));
780 BOOST_TEST((backendObjPtr !=
nullptr));
786 BOOST_CHECK_NO_THROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));
800 BOOST_TEST(substitutions.size() == 1);
802 std::list<Layer*> expectedSubstitutableLayers{ layersInGraph.at(
"conv1 layer"),
803 layersInGraph.at(
"conv2 layer"),
804 layersInGraph.at(
"conv3 layer"),
805 layersInGraph.at(
"conv4 layer"),
806 layersInGraph.at(
"conv5 layer") };
810 CheckSubstitution(substitution,
811 { subgraphInputSlots.size(), subgraphOutputSlots.size(), subgraphLayers.size() },
812 { subgraphInputSlots.size(), subgraphOutputSlots.size(), 1 },
815 expectedSubstitutableLayers);
819 BOOST_TEST(substitutableSubgraphLayers.front() + 0, expectedSubstitutableLayers.front() + 0);
820 BOOST_TEST(substitutableSubgraphLayers.front() + 1, expectedSubstitutableLayers.front() + 1);
821 BOOST_TEST(substitutableSubgraphLayers.front() + 2, expectedSubstitutableLayers.front() + 2);
822 BOOST_TEST(substitutableSubgraphLayers.front() + 3, expectedSubstitutableLayers.front() + 3);
823 BOOST_TEST(substitutableSubgraphLayers.front() + 4, expectedSubstitutableLayers.front() + 4);
840 void PartiallySupportedSubgraphTestImpl()
843 LayerNameToLayerMap layersInGraph;
847 BOOST_TEST((subgraphPtr !=
nullptr));
853 BOOST_TEST(subgraphInputSlots.size() == 1);
854 BOOST_TEST(subgraphOutputSlots.size() == 1);
855 BOOST_TEST(subgraphLayers.size() == 5);
857 BOOST_TEST(
Contains(layersInGraph,
"conv1 layer"));
858 BOOST_TEST(
Contains(layersInGraph,
"pooling1 layer"));
859 BOOST_TEST(
Contains(layersInGraph,
"pooling2 layer"));
860 BOOST_TEST(
Contains(layersInGraph,
"conv2 layer"));
861 BOOST_TEST(
Contains(layersInGraph,
"pooling3 layer"));
866 BOOST_TEST((backendObjPtr !=
nullptr));
872 BOOST_CHECK_NO_THROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));
886 BOOST_TEST(substitutions.size() == 2);
888 std::sort(substitutions.begin(), substitutions.end(), [](
auto s1,
auto s2) {
889 return strcmp(s1.m_SubstitutableSubgraph.GetLayers().front()->GetName(),
890 s2.m_SubstitutableSubgraph.GetLayers().front()->GetName()) < 0;
893 std::vector<ExpectedSubgraphSize> expectedSubstitutableSubgraphSizes{ { 1, 1, 1 },
895 std::vector<ExpectedSubgraphSize> expectedReplacementSubgraphSizes{ { 1, 1, 1 },
897 std::vector<SubgraphView::InputSlots> expectedSubstitutableInputSlots
899 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv1 layer")->GetInputSlots()),
900 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv2 layer")->GetInputSlots())
902 std::vector<SubgraphView::OutputSlots> expectedSubstitutableOutputSlots
904 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv1 layer")->GetOutputSlots()),
905 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv2 layer")->GetOutputSlots())
907 std::vector<SubgraphView::Layers> expectedSubstitutableLayers
909 { layersInGraph.at(
"conv1 layer") },
910 { layersInGraph.at(
"conv2 layer") }
913 for (
size_t substitutionIndex = 0; substitutionIndex < substitutions.size(); substitutionIndex++)
915 CheckSubstitution(substitutions.at(substitutionIndex),
916 expectedSubstitutableSubgraphSizes.at(substitutionIndex),
917 expectedReplacementSubgraphSizes.at(substitutionIndex),
918 expectedSubstitutableInputSlots.at(substitutionIndex),
919 expectedSubstitutableOutputSlots.at(substitutionIndex),
920 expectedSubstitutableLayers.at(substitutionIndex));
928 BOOST_TEST(failedSubgraphs.size() == 2);
930 std::sort(failedSubgraphs.begin(), failedSubgraphs.end(), [](
auto s1,
auto s2) {
931 return strcmp(s1.GetLayers().front()->GetName(), s2.GetLayers().front()->GetName()) < 0;
934 std::vector<ExpectedSubgraphSize> expectedFailedSubgraphSizes{ { 1, 1, 2 },
936 std::vector<SubgraphView::InputSlots> expectedFailedInputSlots
938 ConvertReferenceTypeToPointerType(layersInGraph.at(
"pooling1 layer")->GetInputSlots()),
939 ConvertReferenceTypeToPointerType(layersInGraph.at(
"pooling3 layer")->GetInputSlots())
941 std::vector<SubgraphView::OutputSlots> expectedFailedOutputSlots
943 ConvertReferenceTypeToPointerType(layersInGraph.at(
"pooling2 layer")->GetOutputSlots()),
944 ConvertReferenceTypeToPointerType(layersInGraph.at(
"pooling3 layer")->GetOutputSlots())
946 std::vector<SubgraphView::Layers> expectedFailedLayers
948 { layersInGraph.at(
"pooling1 layer"),
949 layersInGraph.at(
"pooling2 layer") },
950 { layersInGraph.at(
"pooling3 layer") }
953 for (
size_t failedIndex = 0; failedIndex < failedSubgraphs.size(); failedIndex++)
955 CheckFailedSubgraph(failedSubgraphs.at(failedIndex),
956 expectedFailedSubgraphSizes.at(failedIndex),
957 expectedFailedInputSlots.at(failedIndex),
958 expectedFailedOutputSlots.at(failedIndex),
959 expectedFailedLayers.at(failedIndex));
970 void FullyUnoptimizableSubgraphTestImpl1()
973 LayerNameToLayerMap layersInGraph;
977 BOOST_TEST((subgraphPtr !=
nullptr));
983 BOOST_TEST(subgraphInputSlots.size() == 1);
984 BOOST_TEST(subgraphOutputSlots.size() == 1);
985 BOOST_TEST(subgraphLayers.size() == 1);
987 BOOST_TEST(
Contains(layersInGraph,
"conv layer unoptimizable"));
992 BOOST_TEST((backendObjPtr !=
nullptr));
998 BOOST_CHECK_NO_THROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));
1024 BOOST_TEST(untouchedSubgraphs.size() == 1);
1026 CheckUntouchedSubgraph(untouchedSubgraphs.at(0),
1027 { subgraphInputSlots.size(), subgraphOutputSlots.size(), subgraphLayers.size() },
1029 subgraphOutputSlots,
1034 void PartiallyOptimizableSubgraphTestImpl1()
1037 LayerNameToLayerMap layersInGraph;
1041 BOOST_TEST((subgraphPtr !=
nullptr));
1047 BOOST_TEST(subgraphInputSlots.size() == 1);
1048 BOOST_TEST(subgraphOutputSlots.size() == 1);
1049 BOOST_TEST(subgraphLayers.size() == 5);
1051 BOOST_TEST(
Contains(layersInGraph,
"conv1 layer"));
1052 BOOST_TEST(
Contains(layersInGraph,
"conv2 layer unoptimizable"));
1053 BOOST_TEST(
Contains(layersInGraph,
"conv3 layer"));
1054 BOOST_TEST(
Contains(layersInGraph,
"conv4 layer unoptimizable"));
1055 BOOST_TEST(
Contains(layersInGraph,
"conv5 layer"));
1060 BOOST_TEST((backendObjPtr !=
nullptr));
1066 BOOST_CHECK_NO_THROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));
1080 BOOST_TEST(substitutions.size() == 3);
1082 std::sort(substitutions.begin(), substitutions.end(),
1083 [](
auto s1,
auto s2) {
return strcmp(s1.m_SubstitutableSubgraph.GetLayers().front()->GetName(),
1084 s2.m_SubstitutableSubgraph.GetLayers().front()->GetName()) < 0; });
1086 std::vector<ExpectedSubgraphSize> expectedSubstitutableSubgraphSizes{ { 1, 1, 1 },
1089 std::vector<ExpectedSubgraphSize> expectedReplacementSubgraphSizes{ { 1, 1, 1 },
1092 std::vector<SubgraphView::InputSlots> expectedSubstitutableInputSlots
1094 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv1 layer")->GetInputSlots()),
1095 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv3 layer")->GetInputSlots()),
1096 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv5 layer")->GetInputSlots())
1098 std::vector<SubgraphView::OutputSlots> expectedSubstitutableOutputSlots
1100 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv1 layer")->GetOutputSlots()),
1101 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv3 layer")->GetOutputSlots()),
1102 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv5 layer")->GetOutputSlots())
1104 std::vector<SubgraphView::Layers> expectedSubstitutableLayers
1106 { layersInGraph.at(
"conv1 layer") },
1107 { layersInGraph.at(
"conv3 layer") },
1108 { layersInGraph.at(
"conv5 layer") }
1111 for (
size_t substitutionIndex = 0; substitutionIndex < substitutions.size(); substitutionIndex++)
1113 CheckSubstitution(substitutions.at(substitutionIndex),
1114 expectedSubstitutableSubgraphSizes.at(substitutionIndex),
1115 expectedReplacementSubgraphSizes.at(substitutionIndex),
1116 expectedSubstitutableInputSlots.at(substitutionIndex),
1117 expectedSubstitutableOutputSlots.at(substitutionIndex),
1118 expectedSubstitutableLayers.at(substitutionIndex));
1132 BOOST_TEST(untouchedSubgraphs.size() == 2);
1134 std::sort(untouchedSubgraphs.begin(), untouchedSubgraphs.end(), [](
auto s1,
auto s2) {
1135 return strcmp(s1.GetLayers().front()->GetName(), s2.GetLayers().front()->GetName()) < 0;
1138 std::vector<ExpectedSubgraphSize> expectedUntouchedSubgraphSizes{ { 1, 1, 1 },
1140 std::vector<SubgraphView::InputSlots> expectedUntouchedInputSlots
1142 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv2 layer unoptimizable")->GetInputSlots()),
1143 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv4 layer unoptimizable")->GetInputSlots())
1145 std::vector<SubgraphView::OutputSlots> expectedUntouchedOutputSlots
1147 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv2 layer unoptimizable")->GetOutputSlots()),
1148 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv4 layer unoptimizable")->GetOutputSlots())
1150 std::vector<SubgraphView::Layers> expectedUntouchedLayers
1152 { layersInGraph.at(
"conv2 layer unoptimizable") },
1153 { layersInGraph.at(
"conv4 layer unoptimizable") }
1156 for (
size_t untouchedIndex = 0; untouchedIndex < untouchedSubgraphs.size(); untouchedIndex++)
1158 CheckUntouchedSubgraph(untouchedSubgraphs.at(untouchedIndex),
1159 expectedUntouchedSubgraphSizes.at(untouchedIndex),
1160 expectedUntouchedInputSlots.at(untouchedIndex),
1161 expectedUntouchedOutputSlots.at(untouchedIndex),
1162 expectedUntouchedLayers.at(untouchedIndex));
1168 void PartiallyOptimizableSubgraphTestImpl2()
1171 LayerNameToLayerMap layersInGraph;
1175 BOOST_TEST((subgraphPtr !=
nullptr));
1181 BOOST_TEST(subgraphInputSlots.size() == 2);
1182 BOOST_TEST(subgraphOutputSlots.size() == 1);
1183 BOOST_TEST(subgraphLayers.size() == 4);
1185 BOOST_TEST(
Contains(layersInGraph,
"conv1 layer"));
1186 BOOST_TEST(
Contains(layersInGraph,
"conv2 layer unoptimizable"));
1187 BOOST_TEST(
Contains(layersInGraph,
"conv3 layer"));
1188 BOOST_TEST(
Contains(layersInGraph,
"add layer"));
1193 BOOST_TEST((backendObjPtr !=
nullptr));
1199 BOOST_CHECK_NO_THROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));
1213 BOOST_TEST(substitutions.size() == 1);
1215 ExpectedSubgraphSize expectedSubstitutableSubgraphSizes{ 2, 1, 3 };
1216 ExpectedSubgraphSize expectedReplacementSubgraphSizes{ 2, 1, 1 };
1219 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv1 layer")->GetInputSlots()[0]),
1220 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv3 layer")->GetInputSlots()[0])
1224 ConvertReferenceTypeToPointerType(layersInGraph.at(
"add layer")->GetOutputSlots()[0])
1228 layersInGraph.at(
"conv1 layer"),
1229 layersInGraph.at(
"conv3 layer"),
1230 layersInGraph.at(
"add layer")
1233 CheckSubstitution(substitutions[0],
1234 expectedSubstitutableSubgraphSizes,
1235 expectedReplacementSubgraphSizes,
1236 expectedSubstitutableInputSlots,
1237 expectedSubstitutableOutputSlots,
1238 expectedSubstitutableLayers);
1251 BOOST_TEST(untouchedSubgraphs.size() == 1);
1253 std::vector<ExpectedSubgraphSize> expectedUntouchedSubgraphSizes{ { 1, 1, 1 } };
1254 std::vector<SubgraphView::InputSlots> expectedUntouchedInputSlots
1256 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv2 layer unoptimizable")->GetInputSlots())
1258 std::vector<SubgraphView::OutputSlots> expectedUntouchedOutputSlots
1260 ConvertReferenceTypeToPointerType(layersInGraph.at(
"conv2 layer unoptimizable")->GetOutputSlots())
1262 std::vector<SubgraphView::Layers> expectedUntouchedLayers
1264 { layersInGraph.at(
"conv2 layer unoptimizable") }
1267 for (
size_t untouchedIndex = 0; untouchedIndex < untouchedSubgraphs.size(); untouchedIndex++)
1269 CheckUntouchedSubgraph(untouchedSubgraphs.at(untouchedIndex),
1270 expectedUntouchedSubgraphSizes.at(untouchedIndex),
1271 expectedUntouchedInputSlots.at(untouchedIndex),
1272 expectedUntouchedOutputSlots.at(untouchedIndex),
1273 expectedUntouchedLayers.at(untouchedIndex));
BOOST_AUTO_TEST_SUITE(TensorflowLiteParser)
uint32_t m_PadBottom
Padding bottom value in the height dimension.
uint32_t m_PadLeft
Padding left value in the width dimension.
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
bool AreEqual(const CollectionType &lhs, const CollectionType &rhs)
uint32_t m_PoolWidth
Pooling width value.
A Convolution2dDescriptor for the Convolution2dLayer.
int Connect(InputSlot &destination)
std::vector< OutputSlot * > OutputSlots
The padding fields don't count and are ignored.
PaddingMethod m_PaddingMethod
The padding method to be used. (Exclude, IgnoreValue).
constexpr const char * MockBackendId()
uint32_t m_PadTop
Padding top value in the height dimension.
std::vector< SubgraphView > Subgraphs
std::vector< SubstitutionPair > Substitutions
Copyright (c) 2020 ARM Limited.
SubgraphView m_SubstitutableSubgraph
Subgraph of Layers from the original graph which should be replaced.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
int LayerBindingId
Type of identifiers for bindable layers (inputs, outputs).
The SubgraphView class represents a subgraph of a Graph.
uint32_t m_PoolHeight
Pooling height value.
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
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::unique_ptr< SubgraphView > SubgraphViewPtr
uint32_t m_PadRight
Padding right value in the width dimension.
SubgraphView::InputSlots CreateInputsFrom(const std::vector< Layer *> &layers)
bool Contains(const CollectionType &collection, const typename CollectionType::value_type &item)
const Subgraphs & GetUntouchedSubgraphs() const
const Subgraphs & GetFailedSubgraphs() const
SubgraphView m_ReplacementSubgraph
A subgraph of new layers which will replace layers in m_SubstitutableSubgraph.
BOOST_AUTO_TEST_CASE(CheckConvolution2dLayer)
This layer represents a pooling 2d operation.
std::vector< InputSlot * > InputSlots
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
This layer represents an addition operation.
const InputSlots & GetInputSlots() const
const Substitutions & GetSubstitutions() const
std::unique_ptr< SubgraphView > SubgraphViewPtr
BOOST_AUTO_TEST_SUITE_END()
SubgraphView::SubgraphViewPtr CreateSubgraphViewFrom(SubgraphView::InputSlots &&inputs, SubgraphView::OutputSlots &&outputs, SubgraphView::Layers &&layers)
SubgraphView::OutputSlots CreateOutputsFrom(const std::vector< Layer *> &layers)
PoolingAlgorithm m_PoolType
The pooling algorithm to use (Max. Average, L2).
const OutputSlots & GetOutputSlots() const
void SetWeightAndBias(ConvolutionLayer *layer, const armnn::TensorInfo &weightInfo, const armnn::TensorInfo &biasInfo)
void SetTensorInfo(const TensorInfo &tensorInfo) override
armnn::IBackendInternalUniquePtr CreateBackendObject(const armnn::BackendId &backendId)
const Layers & GetLayers() const
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
const char * GetName() const override
Returns the name of the layer.
This layer represents a convolution 2d operation.
A Pooling2dDescriptor for the Pooling2dLayer.
std::list< Layer * > Layers
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.