From 5cf4d1c29a36bb1d675a7cbe2d24b688deb7d160 Mon Sep 17 00:00:00 2001 From: Derek Lamberti Date: Fri, 3 May 2019 18:57:12 +0100 Subject: IVGCVSW-2989 Generate subgraphs without cyclic dependencies Change-Id: I45f81aa4ca8a964e423594fe271825c4a52b21f4 Signed-off-by: Derek Lamberti --- src/armnn/test/SubgraphViewTests.cpp | 87 ++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'src/armnn/test') diff --git a/src/armnn/test/SubgraphViewTests.cpp b/src/armnn/test/SubgraphViewTests.cpp index 4a9316428b..d580385797 100644 --- a/src/armnn/test/SubgraphViewTests.cpp +++ b/src/armnn/test/SubgraphViewTests.cpp @@ -1028,4 +1028,91 @@ BOOST_AUTO_TEST_CASE(MultipleSubgraphs) } } +BOOST_AUTO_TEST_CASE(SubgraphCycles) +{ + // This case represent the scenario when a naive split could lead to a cyclic dependency between two subgraphs + // + // X0 -> M0 -> X1 -> M2 -> X2 + // X0 -> M0 -> M1 -> M2 -> X2 + // + /* + X0 + | + | + M0 + / | + / | + X1 M1 + \ / + M2 + | + X2 + */ + // The expected result for this is that M0,M1 will be part of one subgraph and M2 in another and the + // input and output slots in the subgraphs will be set accordingly. + // + Graph graph; + + OriginsDescriptor mergerDescriptor(2); + auto x0 = graph.AddLayer(0, "x0"); + auto m0 = graph.AddLayer(ActivationDescriptor{}, "m0"); + auto x1 = graph.AddLayer(ActivationDescriptor{}, "x1"); + auto m1 = graph.AddLayer(ActivationDescriptor{}, "m1"); + auto m2 = graph.AddLayer("m2"); + auto x2 = graph.AddLayer(ActivationDescriptor{}, "x2"); + + x0->GetOutputSlot(0).Connect(m0->GetInputSlot(0)); + m0->GetOutputSlot(0).Connect(x1->GetInputSlot(0)); + m0->GetOutputSlot(0).Connect(m1->GetInputSlot(0)); + x1->GetOutputSlot(0).Connect(m2->GetInputSlot(0)); + m1->GetOutputSlot(0).Connect(m2->GetInputSlot(1)); + m2->GetOutputSlot(0).Connect(x2->GetInputSlot(0)); + + // All selected 'M*' layers will be have 'm' in the name + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( + graph, + // select the middle layers only + [](const Layer & l) + { + bool toSelect = (l.GetNameStr().find('m') != std::string::npos); + return toSelect; + }); + + // expected results to test against + auto inputSubgraph = CreateSubgraphViewFrom(CreateInputsFrom({m0}), + CreateOutputsFrom({m0, m1}), + {m0, m1}); + + auto outputSubgraph = CreateSubgraphViewFrom(CreateInputsFrom({m2}), + CreateOutputsFrom({m2}), + {m2}); + + BOOST_TEST(subgraphs.size() == 2); + if (subgraphs.size() == 2) + { + // we need to have valid subgraph pointers here + BOOST_TEST((subgraphs[0] != nullptr)); + BOOST_TEST((subgraphs[1] != nullptr)); + + if (subgraphs[0].get() != nullptr && subgraphs[1].get() != nullptr) + { + // sort the subgraphs by layer size, so it is simpler to test + std::sort(subgraphs.begin(), subgraphs.end(), + [](SubgraphViewSelector::SubgraphViewPtr & lhs, SubgraphViewSelector::SubgraphViewPtr & rhs) + { + return (lhs->GetLayers().size() < rhs->GetLayers().size()); + } + ); + + // one subgraph needs to be size=1 and the other one is 4 + BOOST_TEST(subgraphs[0]->GetLayers().size() == 1); + BOOST_TEST(subgraphs[1]->GetLayers().size() == 2); + + CompareSubgraphViews(subgraphs[0], outputSubgraph); + CompareSubgraphViews(subgraphs[1], inputSubgraph); + } + } +} + BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.1