aboutsummaryrefslogtreecommitdiff
path: root/src/backends
diff options
context:
space:
mode:
authorFrancis Murtagh <francis.murtagh@arm.com>2021-12-13 18:48:12 +0000
committerFrancis Murtagh <francis.murtagh@arm.com>2022-01-14 16:01:58 +0000
commit56ccf68c7858560f2ba00f19076b3cb112970881 (patch)
tree6e19cd38aa1d452ca3b9a9a1f68ff42dd64dc1d7 /src/backends
parent2db6d5aff3d4f596d4b4018a7b454c2a2c8f7122 (diff)
downloadarmnn-56ccf68c7858560f2ba00f19076b3cb112970881.tar.gz
IVGCVSW-6633 SubgraphView uses IConnectableLayer rather than Layer in its m_Layers
* Added IInputSlot, IOutputSlot and IConnectableLayer to SubgraphView * Deprecated old member functions * Removed deprecated calls in ArmNN * Added GetOwningIConnectableLayer function to IOutputSlot * Updates ArmNN Core Major version for IOutputSlot ABI break * Updated Minor version of TfliteParser, OnnxParser and Delegate Signed-off-by: Francis Murtagh <francis.murtagh@arm.com> Change-Id: I2a8611bfabf5ae09d3602fe6a4bef166e18117b9
Diffstat (limited to 'src/backends')
-rw-r--r--src/backends/aclCommon/ArmComputeSubgraphUtils.hpp56
-rw-r--r--src/backends/backendsCommon/OptimizationViews.cpp20
-rw-r--r--src/backends/backendsCommon/test/MockBackend.cpp14
-rw-r--r--src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp248
-rw-r--r--src/backends/cl/ClBackend.cpp18
-rw-r--r--src/backends/neon/NeonBackend.cpp18
6 files changed, 216 insertions, 158 deletions
diff --git a/src/backends/aclCommon/ArmComputeSubgraphUtils.hpp b/src/backends/aclCommon/ArmComputeSubgraphUtils.hpp
index 4367de1e28..74ab789402 100644
--- a/src/backends/aclCommon/ArmComputeSubgraphUtils.hpp
+++ b/src/backends/aclCommon/ArmComputeSubgraphUtils.hpp
@@ -19,14 +19,15 @@ namespace
//
// this helper only works if all layers where the inputs connect to are not selected
//
-SubgraphView::InputSlots CreateInputsFrom(const std::vector<Layer*>& layers)
+
+SubgraphView::IInputSlots CreateIInputsFrom(const std::vector<armnn::IConnectableLayer*>& layers)
{
- SubgraphView::InputSlots result;
+ SubgraphView::IInputSlots result;
for (auto&& layer : layers)
{
- for (auto&& it = layer->BeginInputSlots(); it != layer->EndInputSlots(); ++it)
+ for (unsigned int i = 0 ; i < layer->GetNumInputSlots(); ++i)
{
- result.push_back(&(*it));
+ result.push_back(&(layer->GetInputSlot(i)));
}
}
return result;
@@ -35,14 +36,15 @@ SubgraphView::InputSlots CreateInputsFrom(const std::vector<Layer*>& layers)
//
// this helper only works if all layers where the outputs connect to are not selected
//
-SubgraphView::OutputSlots CreateOutputsFrom(const std::vector<Layer*>& layers)
+
+SubgraphView::IOutputSlots CreateIOutputsFrom(const std::vector<armnn::IConnectableLayer*>& layers)
{
- SubgraphView::OutputSlots result;
- for (auto&& layer : layers)
+ SubgraphView::IOutputSlots result;
+ for (auto &&layer: layers)
{
- for (auto&& it = layer->BeginOutputSlots(); it != layer->EndOutputSlots(); ++it)
+ for (unsigned int i = 0; i < layer->GetNumOutputSlots(); ++i)
{
- result.push_back(&(*it));
+ result.push_back(&(layer->GetOutputSlot(i)));
}
}
return result;
@@ -83,9 +85,9 @@ inline void ReportUntouchedLayers(OptimizationViews& optimizationViews, std::map
for (const auto& pair : untouched)
{
Layer* layer = pair.second;
- SubgraphView subgraphView(CreateInputsFrom({layer}),
- CreateOutputsFrom({layer}),
- {layer});
+ SubgraphView subgraphView({layer},
+ CreateIInputsFrom({layer}),
+ CreateIOutputsFrom({layer}));
optimizationViews.AddUntouchedSubgraph(std::move(subgraphView));
}
}
@@ -100,9 +102,9 @@ LayerType* FuseLayer(OptimizationViews& optimizationViews,
replacementLayer->SetAdditionalInfoForObject(
std::make_shared<ActivationDescriptor>(activationDesc));
- SubgraphView substitutionSubgraph(CreateInputsFrom({baseLayer}),
- CreateOutputsFrom({activationLayer}),
- {baseLayer, activationLayer});
+ SubgraphView substitutionSubgraph({baseLayer, activationLayer},
+ CreateIInputsFrom({baseLayer}),
+ CreateIOutputsFrom({activationLayer}));
SubgraphView replacementSubgraph(replacementLayer);
optimizationViews.AddSubstitution({substitutionSubgraph, replacementSubgraph});
@@ -208,6 +210,11 @@ LayerType* FuseBatchNormalizationLayer(OptimizationViews& optimizationViews,
activationLayer,
activationDesc);
+ SubgraphView substitutionSubgraph({baseLayer, activationLayer},
+ CreateIInputsFrom({baseLayer}),
+ CreateIOutputsFrom({activationLayer}));
+ SubgraphView replacementSubgraph(replacementLayer);
+
return replacementLayer;
}
@@ -316,12 +323,12 @@ LayerType* FuseFullyConnectedLayer(OptimizationViews& optimizationViews,
// as currently only one axis is supported.
//
template<typename LayerType>
-std::vector<Layer*> ChainReduceLayers(OptimizationViews& optimizationViews,
+std::vector<IConnectableLayer*> ChainReduceLayers(OptimizationViews& optimizationViews,
LayerType* baseLayer,
ReduceDescriptor& desc)
{
// Vector of new chained layers, used for substitution.
- std::vector<Layer*> layers;
+ std::vector<IConnectableLayer*> layers;
// Vector of axes so each layer is reshaped correctly.
std::vector<uint32_t> axes;
@@ -348,9 +355,11 @@ std::vector<Layer*> ChainReduceLayers(OptimizationViews& optimizationViews,
// Add new layer to graph.
std::string layerName = "reduce_layer_" + std::to_string(i);
+
Layer* replacementLayer = PolymorphicDowncast<Layer*>(
optimizationViews.GetINetwork()->AddReduceLayer(newReduceDescriptor,
layerName.c_str()));
+
// Connect previous layer with new layer.
// The first and last layer will be connected when the subgraph is replaced.
if (!layers.empty())
@@ -370,7 +379,8 @@ std::vector<Layer*> ChainReduceLayers(OptimizationViews& optimizationViews,
}
// Check if the TensorInfo from the last layer equals the inferred output from the original layer.
- ARMNN_ASSERT(baseLayer->GetOutputSlot(0).GetTensorInfo() == layers.back()->GetOutputSlot().GetTensorInfo());
+ ARMNN_ASSERT(baseLayer->GetOutputSlot(0).GetTensorInfo() ==
+ PolymorphicDowncast<Layer*>(layers.back())->GetOutputSlot().GetTensorInfo());
return layers;
}
@@ -381,14 +391,14 @@ std::vector<Layer*> ChainReduceLayers(OptimizationViews& optimizationViews,
template<typename LayerType>
void ReplaceLayers(OptimizationViews& optimizationViews,
LayerType* baseLayer,
- std::vector<Layer*>& layers)
+ std::vector<IConnectableLayer*>& layers)
{
- std::list<Layer*> replacementLayers(layers.begin(), layers.end());
+ std::list<IConnectableLayer*> replacementLayers(layers.begin(), layers.end());
SubgraphView substitutionSubgraph(baseLayer);
- SubgraphView replacementSubgraph(CreateInputsFrom({replacementLayers.front()}),
- CreateOutputsFrom({replacementLayers.back()}),
- std::move(replacementLayers));
+ SubgraphView replacementSubgraph(std::move(replacementLayers),
+ CreateIInputsFrom({replacementLayers.front()}),
+ CreateIOutputsFrom({replacementLayers.back()}));
optimizationViews.AddSubstitution({substitutionSubgraph, replacementSubgraph});
}
diff --git a/src/backends/backendsCommon/OptimizationViews.cpp b/src/backends/backendsCommon/OptimizationViews.cpp
index eee2c67ea9..e81a6912a1 100644
--- a/src/backends/backendsCommon/OptimizationViews.cpp
+++ b/src/backends/backendsCommon/OptimizationViews.cpp
@@ -17,24 +17,28 @@ bool OptimizationViews::Validate(const armnn::SubgraphView& originalSubgraph) co
bool valid = true;
// Create a copy of the layer list from the original subgraph and sort it
- SubgraphView::Layers originalLayers = originalSubgraph.GetLayers();
+ SubgraphView::IConnectableLayers originalLayers = originalSubgraph.GetIConnectableLayers();
originalLayers.sort();
// Create a new list based on the sum of all the subgraphs and sort it
- SubgraphView::Layers countedLayers;
+ SubgraphView::IConnectableLayers countedLayers;
for (auto& failed : m_FailedOptimizations)
{
- countedLayers.insert(countedLayers.end(), failed.GetLayers().begin(), failed.GetLayers().end());
+ countedLayers.insert(countedLayers.end(),
+ failed.GetIConnectableLayers().begin(),
+ failed.GetIConnectableLayers().end());
}
for (auto& untouched : m_UntouchedSubgraphs)
{
- countedLayers.insert(countedLayers.end(), untouched.GetLayers().begin(), untouched.GetLayers().end());
+ countedLayers.insert(countedLayers.end(),
+ untouched.GetIConnectableLayers().begin(),
+ untouched.GetIConnectableLayers().end());
}
for (auto& successful : m_SuccesfulOptimizations)
{
countedLayers.insert(countedLayers.end(),
- successful.m_SubstitutableSubgraph.GetLayers().begin(),
- successful.m_SubstitutableSubgraph.GetLayers().end());
+ successful.m_SubstitutableSubgraph.GetIConnectableLayers().begin(),
+ successful.m_SubstitutableSubgraph.GetIConnectableLayers().end());
}
countedLayers.sort();
@@ -56,8 +60,8 @@ bool OptimizationViews::Validate(const armnn::SubgraphView& originalSubgraph) co
bool validSubstitution = true;
const SubgraphView& replacement = substitution.m_ReplacementSubgraph;
const SubgraphView& old = substitution.m_SubstitutableSubgraph;
- validSubstitution &= replacement.GetInputSlots().size() == old.GetInputSlots().size();
- validSubstitution &= replacement.GetOutputSlots().size() == old.GetOutputSlots().size();
+ validSubstitution &= replacement.GetIInputSlots().size() == old.GetIInputSlots().size();
+ validSubstitution &= replacement.GetIOutputSlots().size() == old.GetIOutputSlots().size();
valid &= validSubstitution;
}
}
diff --git a/src/backends/backendsCommon/test/MockBackend.cpp b/src/backends/backendsCommon/test/MockBackend.cpp
index d95cfc3a34..2ce14f92a4 100644
--- a/src/backends/backendsCommon/test/MockBackend.cpp
+++ b/src/backends/backendsCommon/test/MockBackend.cpp
@@ -130,21 +130,21 @@ OptimizationViews MockBackend::OptimizeSubgraphView(const SubgraphView& subgraph
OptimizationViews optimizationViews;
// Get the layers of the input sub-graph
- const SubgraphView::Layers& subgraphLayers = subgraph.GetLayers();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraph.GetIConnectableLayers();
// Parse the layers
- SubgraphView::Layers supportedLayers;
- SubgraphView::Layers unsupportedLayers;
- SubgraphView::Layers untouchedLayers;
+ SubgraphView::IConnectableLayers supportedLayers;
+ SubgraphView::IConnectableLayers unsupportedLayers;
+ SubgraphView::IConnectableLayers untouchedLayers;
std::for_each(subgraphLayers.begin(),
subgraphLayers.end(),
- [&](Layer* layer)
+ [&](IConnectableLayer* layer)
{
- bool supported = IsLayerSupported(layer);
+ bool supported = IsLayerSupported(PolymorphicDowncast<Layer*>(layer));
if (supported)
{
// Layer supported, check if it's optimizable
- bool optimizable = IsLayerOptimizable(layer);
+ bool optimizable = IsLayerOptimizable(PolymorphicDowncast<Layer*>(layer));
if (optimizable)
{
// Layer fully supported
diff --git a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
index 4dd6bc955d..8036b41fb2 100644
--- a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
+++ b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
@@ -56,6 +56,18 @@ std::vector<SlotType*> ConvertReferenceTypeToPointerType(const std::vector<SlotT
return output;
}
+// Convert from vector of Slots* (Input/Output) to vector of ISlots* (IInput/IOutput)
+template <typename SlotType, typename ResultSlotType>
+std::vector<ResultSlotType*> ConvertSlotsToISlots(const std::vector<SlotType*> input)
+{
+ std::vector<ResultSlotType*> output;
+ for (auto slot : input)
+ {
+ output.push_back(PolymorphicDowncast<ResultSlotType*>(slot));
+ }
+ return output;
+}
+
// Convenience function to add an input layer to a graph
Layer* AddInputLayer(Graph& graph,
const std::string& layerName,
@@ -125,19 +137,20 @@ AdditionLayer* AddAdditionaLayer(Graph& graph,
void CheckSubstitution(const OptimizationViews::SubstitutionPair& substitution,
const ExpectedSubgraphSize& expectedSubstitutableSubgraphSize,
const ExpectedSubgraphSize& expectedReplacementSubgraphSize,
- const SubgraphView::InputSlots& expectedSubstitutableInputSlots,
- const SubgraphView::OutputSlots& expectedSubstitutableOutputSlots,
- const SubgraphView::Layers& expectedSubstitutableLayers)
+ const SubgraphView::IInputSlots& expectedSubstitutableInputSlots,
+ const SubgraphView::IOutputSlots& expectedSubstitutableOutputSlots,
+ const SubgraphView::IConnectableLayers& expectedSubstitutableLayers)
{
- const SubgraphView& substitutableSubgraph = substitution.m_SubstitutableSubgraph;
- const SubgraphView::InputSlots& substitutableSubgraphInputSlots = substitutableSubgraph.GetInputSlots();
- const SubgraphView::OutputSlots& substitutableSubgraphOutputSlots = substitutableSubgraph.GetOutputSlots();
- const SubgraphView::Layers& substitutableSubgraphLayers = substitutableSubgraph.GetLayers();
+ const SubgraphView& substitutableSubgraph = substitution.m_SubstitutableSubgraph;
+ const SubgraphView::IInputSlots& substitutableSubgraphInputSlots = substitutableSubgraph.GetIInputSlots();
+ const SubgraphView::IOutputSlots& substitutableSubgraphOutputSlots = substitutableSubgraph.GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& substitutableSubgraphLayers =
+ substitutableSubgraph.GetIConnectableLayers();
- const SubgraphView& replacementSubgraph = substitution.m_ReplacementSubgraph;
- const SubgraphView::InputSlots& replacementSubgraphInputSlots = replacementSubgraph.GetInputSlots();
- const SubgraphView::OutputSlots& replacementSubgraphOutputSlots = replacementSubgraph.GetOutputSlots();
- const SubgraphView::Layers& replacementSubgraphLayers = replacementSubgraph.GetLayers();
+ const SubgraphView& replacementSubgraph = substitution.m_ReplacementSubgraph;
+ const SubgraphView::IInputSlots& replacementSubgraphInputSlots = replacementSubgraph.GetIInputSlots();
+ const SubgraphView::IOutputSlots& replacementSubgraphOutputSlots = replacementSubgraph.GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& replacementSubgraphLayers = replacementSubgraph.GetIConnectableLayers();
CHECK(substitutableSubgraphInputSlots.size() == expectedSubstitutableSubgraphSize.m_NumInputSlots);
CHECK(substitutableSubgraphOutputSlots.size() == expectedSubstitutableSubgraphSize.m_NumOutputSlots);
@@ -157,7 +170,7 @@ void CheckSubstitution(const OptimizationViews::SubstitutionPair& substitution,
CHECK(std::all_of(replacementSubgraphLayers.begin(),
replacementSubgraphLayers.end(),
- [](const Layer* layer)
+ [](const IConnectableLayer* layer)
{
return layer->GetType() == LayerType::PreCompiled;
}));
@@ -166,13 +179,13 @@ void CheckSubstitution(const OptimizationViews::SubstitutionPair& substitution,
// Convenience function to check that the given failed subgraph matches the specified expected values
void CheckFailedSubgraph(const SubgraphView& failedSubgraph,
const ExpectedSubgraphSize& expectedFailedSubgraphSize,
- const SubgraphView::InputSlots& expectedFailedInputSlots,
- const SubgraphView::OutputSlots& expectedFailedOutputSlots,
- const SubgraphView::Layers& expectedFailedLayers)
+ const SubgraphView::IInputSlots& expectedFailedInputSlots,
+ const SubgraphView::IOutputSlots& expectedFailedOutputSlots,
+ const SubgraphView::IConnectableLayers& expectedFailedLayers)
{
- const SubgraphView::InputSlots& failedSubgraphInputSlots = failedSubgraph.GetInputSlots();
- const SubgraphView::OutputSlots& failedSubgraphOutputSlots = failedSubgraph.GetOutputSlots();
- const SubgraphView::Layers& failedSubgraphLayers = failedSubgraph.GetLayers();
+ const SubgraphView::IInputSlots& failedSubgraphInputSlots = failedSubgraph.GetIInputSlots();
+ const SubgraphView::IOutputSlots& failedSubgraphOutputSlots = failedSubgraph.GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& failedSubgraphLayers = failedSubgraph.GetIConnectableLayers();
CHECK(failedSubgraphInputSlots.size() == expectedFailedSubgraphSize.m_NumInputSlots);
CHECK(failedSubgraphOutputSlots.size() == expectedFailedSubgraphSize.m_NumOutputSlots);
@@ -186,13 +199,13 @@ void CheckFailedSubgraph(const SubgraphView& failedSubgraph,
// Convenience function to check that the given untouched subgraph matches the specified expected values
void CheckUntouchedSubgraph(const SubgraphView& untouchedSubgraph,
const ExpectedSubgraphSize& expectedUntouchedSubgraphSize,
- const SubgraphView::InputSlots& expectedUntouchedInputSlots,
- const SubgraphView::OutputSlots& expectedUntouchedOutputSlots,
- const SubgraphView::Layers& expectedUntouchedLayers)
+ const SubgraphView::IInputSlots& expectedUntouchedInputSlots,
+ const SubgraphView::IOutputSlots& expectedUntouchedOutputSlots,
+ const SubgraphView::IConnectableLayers& expectedUntouchedLayers)
{
- const SubgraphView::InputSlots& untouchedSubgraphInputSlots = untouchedSubgraph.GetInputSlots();
- const SubgraphView::OutputSlots& untouchedSubgraphOutputSlots = untouchedSubgraph.GetOutputSlots();
- const SubgraphView::Layers& untouchedSubgraphLayers = untouchedSubgraph.GetLayers();
+ const SubgraphView::IInputSlots& untouchedSubgraphInputSlots = untouchedSubgraph.GetIInputSlots();
+ const SubgraphView::IOutputSlots& untouchedSubgraphOutputSlots = untouchedSubgraph.GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& untouchedSubgraphLayers = untouchedSubgraph.GetIConnectableLayers();
CHECK(untouchedSubgraphInputSlots.size() == expectedUntouchedSubgraphSize.m_NumInputSlots);
CHECK(untouchedSubgraphOutputSlots.size() == expectedUntouchedSubgraphSize.m_NumOutputSlots);
@@ -552,9 +565,9 @@ void FullyUnsupporteSubgraphTestImpl1()
SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyUnsupportedSubgraph1(graph, layersInGraph);
CHECK((subgraphPtr != nullptr));
- const SubgraphView::InputSlots& subgraphInputSlots = subgraphPtr->GetInputSlots();
- const SubgraphView::OutputSlots& subgraphOutputSlots = subgraphPtr->GetOutputSlots();
- const SubgraphView::Layers& subgraphLayers = subgraphPtr->GetLayers();
+ const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
+ const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();
CHECK(subgraphInputSlots.size() == 1);
CHECK(subgraphOutputSlots.size() == 1);
@@ -616,9 +629,9 @@ void FullyUnsupporteSubgraphTestImpl2()
SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyUnsupportedSubgraph2(graph, layersInGraph);
CHECK((subgraphPtr != nullptr));
- const SubgraphView::InputSlots& subgraphInputSlots = subgraphPtr->GetInputSlots();
- const SubgraphView::OutputSlots& subgraphOutputSlots = subgraphPtr->GetOutputSlots();
- const SubgraphView::Layers& subgraphLayers = subgraphPtr->GetLayers();
+ const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
+ const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();
CHECK(subgraphInputSlots.size() == 1);
CHECK(subgraphOutputSlots.size() == 1);
@@ -659,7 +672,7 @@ void FullyUnsupporteSubgraphTestImpl2()
const OptimizationViews::Subgraphs& failedSubgraphs = optimizationViews.GetFailedSubgraphs();
CHECK(failedSubgraphs.size() == 1);
- std::list<Layer*> expectedFailedLayers{ layersInGraph.at("pooling1 layer"),
+ std::list<IConnectableLayer*> expectedFailedLayers{ layersInGraph.at("pooling1 layer"),
layersInGraph.at("pooling2 layer"),
layersInGraph.at("pooling3 layer") };
@@ -671,7 +684,7 @@ void FullyUnsupporteSubgraphTestImpl2()
subgraphOutputSlots,
subgraphLayers);
- const SubgraphView::Layers& failedSubgraphLayers = failedSubgraph.GetLayers();
+ const SubgraphView::IConnectableLayers& failedSubgraphLayers = failedSubgraph.GetIConnectableLayers();
CHECK_EQ(failedSubgraphLayers.front() + 0, expectedFailedLayers.front() + 0);
CHECK_EQ(failedSubgraphLayers.front() + 1, expectedFailedLayers.front() + 1);
@@ -694,9 +707,9 @@ void FullyOptimizableSubgraphTestImpl1()
SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildFullyOptimizableSubgraph1(graph, layersInGraph);
CHECK((subgraphPtr != nullptr));
- const SubgraphView::InputSlots& subgraphInputSlots = subgraphPtr->GetInputSlots();
- const SubgraphView::OutputSlots& subgraphOutputSlots = subgraphPtr->GetOutputSlots();
- const SubgraphView::Layers& subgraphLayers = subgraphPtr->GetLayers();
+ const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
+ const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();
CHECK(subgraphInputSlots.size() == 1);
CHECK(subgraphOutputSlots.size() == 1);
@@ -759,13 +772,13 @@ void FullyOptimizableSubgraphTestImpl2()
SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildFullyOptimizableSubgraph2(graph, layersInGraph);
CHECK((subgraphPtr != nullptr));
- const SubgraphView::InputSlots& subgraphInputSlots = subgraphPtr->GetInputSlots();
- const SubgraphView::OutputSlots& subgraphOutputSlots = subgraphPtr->GetOutputSlots();
- const SubgraphView::Layers& subgraphLayers = subgraphPtr->GetLayers();
+ const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
+ const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();
- CHECK(subgraphPtr->GetInputSlots().size() == 1);
- CHECK(subgraphPtr->GetOutputSlots().size() == 1);
- CHECK(subgraphPtr->GetLayers().size() == 5);
+ CHECK(subgraphPtr->GetIInputSlots().size() == 1);
+ CHECK(subgraphPtr->GetIOutputSlots().size() == 1);
+ CHECK(subgraphPtr->GetIConnectableLayers().size() == 5);
CHECK(Contains(layersInGraph, "conv1 layer"));
CHECK(Contains(layersInGraph, "conv2 layer"));
@@ -798,7 +811,7 @@ void FullyOptimizableSubgraphTestImpl2()
const OptimizationViews::Substitutions& substitutions = optimizationViews.GetSubstitutions();
CHECK(substitutions.size() == 1);
- std::list<Layer*> expectedSubstitutableLayers{ layersInGraph.at("conv1 layer"),
+ std::list<IConnectableLayer*> expectedSubstitutableLayers{ layersInGraph.at("conv1 layer"),
layersInGraph.at("conv2 layer"),
layersInGraph.at("conv3 layer"),
layersInGraph.at("conv4 layer"),
@@ -813,7 +826,8 @@ void FullyOptimizableSubgraphTestImpl2()
subgraphOutputSlots,
expectedSubstitutableLayers);
- const SubgraphView::Layers& substitutableSubgraphLayers = substitution.m_SubstitutableSubgraph.GetLayers();
+ const SubgraphView::IConnectableLayers& substitutableSubgraphLayers =
+ substitution.m_SubstitutableSubgraph.GetIConnectableLayers();
CHECK_EQ(substitutableSubgraphLayers.front() + 0, expectedSubstitutableLayers.front() + 0);
CHECK_EQ(substitutableSubgraphLayers.front() + 1, expectedSubstitutableLayers.front() + 1);
@@ -845,9 +859,9 @@ void PartiallySupportedSubgraphTestImpl()
SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildPartiallySupportedSubgraph(graph, layersInGraph);
CHECK((subgraphPtr != nullptr));
- const SubgraphView::InputSlots& subgraphInputSlots = subgraphPtr->GetInputSlots();
- const SubgraphView::OutputSlots& subgraphOutputSlots = subgraphPtr->GetOutputSlots();
- const SubgraphView::Layers& subgraphLayers = subgraphPtr->GetLayers();
+ const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
+ const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();
CHECK(subgraphInputSlots.size() == 1);
CHECK(subgraphOutputSlots.size() == 1);
@@ -885,25 +899,30 @@ void PartiallySupportedSubgraphTestImpl()
CHECK(substitutions.size() == 2);
// Sort into a consistent order
std::sort(substitutions.begin(), substitutions.end(), [](auto s1, auto s2) {
- return strcmp(s1.m_SubstitutableSubgraph.GetLayers().front()->GetName(),
- s2.m_SubstitutableSubgraph.GetLayers().front()->GetName()) < 0;
+ return strcmp(s1.m_SubstitutableSubgraph.GetIConnectableLayers().front()->GetName(),
+ s2.m_SubstitutableSubgraph.GetIConnectableLayers().front()->GetName()) < 0;
});
std::vector<ExpectedSubgraphSize> expectedSubstitutableSubgraphSizes{ { 1, 1, 1 },
{ 1, 1, 1 } };
std::vector<ExpectedSubgraphSize> expectedReplacementSubgraphSizes{ { 1, 1, 1 },
{ 1, 1, 1 } };
- std::vector<SubgraphView::InputSlots> expectedSubstitutableInputSlots
+ std::vector<SubgraphView::IInputSlots> expectedSubstitutableInputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer")->GetInputSlots())
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlots())),
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer")->GetInputSlots()))
};
- std::vector<SubgraphView::OutputSlots> expectedSubstitutableOutputSlots
+
+ std::vector<SubgraphView::IOutputSlots> expectedSubstitutableOutputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetOutputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer")->GetOutputSlots())
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetOutputSlots())),
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer")->GetOutputSlots()))
};
- std::vector<SubgraphView::Layers> expectedSubstitutableLayers
+ std::vector<SubgraphView::IConnectableLayers> expectedSubstitutableLayers
{
{ layersInGraph.at("conv1 layer") },
{ layersInGraph.at("conv2 layer") }
@@ -927,22 +946,27 @@ void PartiallySupportedSubgraphTestImpl()
CHECK(failedSubgraphs.size() == 2);
// Sort into a consistent order
std::sort(failedSubgraphs.begin(), failedSubgraphs.end(), [](auto s1, auto s2) {
- return strcmp(s1.GetLayers().front()->GetName(), s2.GetLayers().front()->GetName()) < 0;
+ return strcmp(s1.GetIConnectableLayers().front()->GetName(),
+ s2.GetIConnectableLayers().front()->GetName()) < 0;
});
std::vector<ExpectedSubgraphSize> expectedFailedSubgraphSizes{ { 1, 1, 2 },
{ 1, 1, 1 } };
- std::vector<SubgraphView::InputSlots> expectedFailedInputSlots
+ std::vector<SubgraphView::IInputSlots> expectedFailedInputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("pooling1 layer")->GetInputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("pooling3 layer")->GetInputSlots())
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("pooling1 layer")->GetInputSlots())),
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("pooling3 layer")->GetInputSlots()))
};
- std::vector<SubgraphView::OutputSlots> expectedFailedOutputSlots
+ std::vector<SubgraphView::IOutputSlots> expectedFailedOutputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("pooling2 layer")->GetOutputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("pooling3 layer")->GetOutputSlots())
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("pooling2 layer")->GetOutputSlots())),
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("pooling3 layer")->GetOutputSlots()))
};
- std::vector<SubgraphView::Layers> expectedFailedLayers
+ std::vector<SubgraphView::IConnectableLayers> expectedFailedLayers
{
{ layersInGraph.at("pooling1 layer"),
layersInGraph.at("pooling2 layer") },
@@ -975,9 +999,9 @@ void FullyUnoptimizableSubgraphTestImpl1()
SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildFullyUnoptimizableSubgraph1(graph, layersInGraph);
CHECK((subgraphPtr != nullptr));
- const SubgraphView::InputSlots& subgraphInputSlots = subgraphPtr->GetInputSlots();
- const SubgraphView::OutputSlots& subgraphOutputSlots = subgraphPtr->GetOutputSlots();
- const SubgraphView::Layers& subgraphLayers = subgraphPtr->GetLayers();
+ const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
+ const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();
CHECK(subgraphInputSlots.size() == 1);
CHECK(subgraphOutputSlots.size() == 1);
@@ -1039,9 +1063,9 @@ void PartiallyOptimizableSubgraphTestImpl1()
SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildPartiallyOptimizableSubgraph1(graph, layersInGraph);
CHECK((subgraphPtr != nullptr));
- const SubgraphView::InputSlots& subgraphInputSlots = subgraphPtr->GetInputSlots();
- const SubgraphView::OutputSlots& subgraphOutputSlots = subgraphPtr->GetOutputSlots();
- const SubgraphView::Layers& subgraphLayers = subgraphPtr->GetLayers();
+ const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
+ const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();
CHECK(subgraphInputSlots.size() == 1);
CHECK(subgraphOutputSlots.size() == 1);
@@ -1079,8 +1103,9 @@ void PartiallyOptimizableSubgraphTestImpl1()
CHECK(substitutions.size() == 3);
// Sort into a consistent order
std::sort(substitutions.begin(), substitutions.end(),
- [](auto s1, auto s2) { return strcmp(s1.m_SubstitutableSubgraph.GetLayers().front()->GetName(),
- s2.m_SubstitutableSubgraph.GetLayers().front()->GetName()) < 0; });
+ [](auto s1, auto s2)
+ { return strcmp(s1.m_SubstitutableSubgraph.GetIConnectableLayers().front()->GetName(),
+ s2.m_SubstitutableSubgraph.GetIConnectableLayers().front()->GetName()) < 0; });
std::vector<ExpectedSubgraphSize> expectedSubstitutableSubgraphSizes{ { 1, 1, 1 },
{ 1, 1, 1 },
@@ -1088,19 +1113,25 @@ void PartiallyOptimizableSubgraphTestImpl1()
std::vector<ExpectedSubgraphSize> expectedReplacementSubgraphSizes{ { 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 } };
- std::vector<SubgraphView::InputSlots> expectedSubstitutableInputSlots
+ std::vector<SubgraphView::IInputSlots> expectedSubstitutableInputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetInputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv5 layer")->GetInputSlots())
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlots())),
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetInputSlots())),
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv5 layer")->GetInputSlots()))
};
- std::vector<SubgraphView::OutputSlots> expectedSubstitutableOutputSlots
+ std::vector<SubgraphView::IOutputSlots> expectedSubstitutableOutputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetOutputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetOutputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv5 layer")->GetOutputSlots())
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetOutputSlots())),
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetOutputSlots())),
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv5 layer")->GetOutputSlots()))
};
- std::vector<SubgraphView::Layers> expectedSubstitutableLayers
+ std::vector<SubgraphView::IConnectableLayers> expectedSubstitutableLayers
{
{ layersInGraph.at("conv1 layer") },
{ layersInGraph.at("conv3 layer") },
@@ -1131,22 +1162,27 @@ void PartiallyOptimizableSubgraphTestImpl1()
CHECK(untouchedSubgraphs.size() == 2);
// Sort into a consistent order
std::sort(untouchedSubgraphs.begin(), untouchedSubgraphs.end(), [](auto s1, auto s2) {
- return strcmp(s1.GetLayers().front()->GetName(), s2.GetLayers().front()->GetName()) < 0;
+ return strcmp(s1.GetIConnectableLayers().front()->GetName(),
+ s2.GetIConnectableLayers().front()->GetName()) < 0;
});
std::vector<ExpectedSubgraphSize> expectedUntouchedSubgraphSizes{ { 1, 1, 1 },
{ 1, 1, 1 } };
- std::vector<SubgraphView::InputSlots> expectedUntouchedInputSlots
+ std::vector<SubgraphView::IInputSlots> expectedUntouchedInputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetInputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv4 layer unoptimizable")->GetInputSlots())
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetInputSlots())),
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv4 layer unoptimizable")->GetInputSlots()))
};
- std::vector<SubgraphView::OutputSlots> expectedUntouchedOutputSlots
+ std::vector<SubgraphView::IOutputSlots> expectedUntouchedOutputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetOutputSlots()),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv4 layer unoptimizable")->GetOutputSlots())
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetOutputSlots())),
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv4 layer unoptimizable")->GetOutputSlots()))
};
- std::vector<SubgraphView::Layers> expectedUntouchedLayers
+ std::vector<SubgraphView::IConnectableLayers> expectedUntouchedLayers
{
{ layersInGraph.at("conv2 layer unoptimizable") },
{ layersInGraph.at("conv4 layer unoptimizable") }
@@ -1173,9 +1209,9 @@ void PartiallyOptimizableSubgraphTestImpl2()
SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildPartiallyOptimizableSubgraph2(graph, layersInGraph);
CHECK((subgraphPtr != nullptr));
- const SubgraphView::InputSlots& subgraphInputSlots = subgraphPtr->GetInputSlots();
- const SubgraphView::OutputSlots& subgraphOutputSlots = subgraphPtr->GetOutputSlots();
- const SubgraphView::Layers& subgraphLayers = subgraphPtr->GetLayers();
+ const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
+ const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
+ const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();
CHECK(subgraphInputSlots.size() == 2);
CHECK(subgraphOutputSlots.size() == 1);
@@ -1214,15 +1250,21 @@ void PartiallyOptimizableSubgraphTestImpl2()
ExpectedSubgraphSize expectedSubstitutableSubgraphSizes{ 2, 1, 3 };
ExpectedSubgraphSize expectedReplacementSubgraphSizes{ 2, 1, 1 };
- SubgraphView::InputSlots expectedSubstitutableInputSlots = {
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlots()[0]),
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetInputSlots()[0])
+ SubgraphView::IInputSlots expectedSubstitutableInputSlots
+ {
+ ConvertSlotsToISlots<InputSlot, IInputSlot>({
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlots()[0])})[0],
+ ConvertSlotsToISlots<InputSlot, IInputSlot>({
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetInputSlots()[0])})[0]
};
- SubgraphView::OutputSlots expectedSubstitutableOutputSlots =
+
+ SubgraphView::IOutputSlots expectedSubstitutableOutputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("add layer")->GetOutputSlots()[0])
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("add layer")->GetOutputSlots()))
};
- SubgraphView::Layers expectedSubstitutableLayers
+
+ SubgraphView::IConnectableLayers expectedSubstitutableLayers
{
layersInGraph.at("conv1 layer"),
layersInGraph.at("conv3 layer"),
@@ -1250,15 +1292,17 @@ void PartiallyOptimizableSubgraphTestImpl2()
CHECK(untouchedSubgraphs.size() == 1);
std::vector<ExpectedSubgraphSize> expectedUntouchedSubgraphSizes{ { 1, 1, 1 } };
- std::vector<SubgraphView::InputSlots> expectedUntouchedInputSlots
+ std::vector<SubgraphView::IInputSlots> expectedUntouchedInputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetInputSlots())
+ ConvertSlotsToISlots<InputSlot, IInputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetInputSlots()))
};
- std::vector<SubgraphView::OutputSlots> expectedUntouchedOutputSlots
+ std::vector<SubgraphView::IOutputSlots> expectedUntouchedOutputSlots
{
- ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetOutputSlots())
+ ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
+ ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetOutputSlots()))
};
- std::vector<SubgraphView::Layers> expectedUntouchedLayers
+ std::vector<SubgraphView::IConnectableLayers> expectedUntouchedLayers
{
{ layersInGraph.at("conv2 layer unoptimizable") }
};
diff --git a/src/backends/cl/ClBackend.cpp b/src/backends/cl/ClBackend.cpp
index 339c1aa398..cf5f50025a 100644
--- a/src/backends/cl/ClBackend.cpp
+++ b/src/backends/cl/ClBackend.cpp
@@ -227,18 +227,18 @@ OptimizationViews ClBackend::OptimizeSubgraphView(const SubgraphView& subgraph,
{
OptimizationViews optimizationViews;
- auto it = subgraph.end();
+ auto it = subgraph.endIConnectable();
bool isFastMathEnabled = false;
std::map<LayerGuid, Layer*> untouched;
- while (it != subgraph.begin())
+ while (it != subgraph.beginIConnectable())
{
--it;
- Layer& base = **it;
+ Layer& base = *(PolymorphicDowncast<Layer*>(*it));
untouched.insert({base.GetGuid(), &base});
}
- it = subgraph.end();
+ it = subgraph.endIConnectable();
#if defined(ARMCOMPUTECL_ENABLED)
IBackendInternal::IBackendSpecificModelContextPtr modelContextPtr = CreateBackendSpecificModelContext(modelOptions);
@@ -251,10 +251,10 @@ OptimizationViews ClBackend::OptimizeSubgraphView(const SubgraphView& subgraph,
}
}
#endif
- while (it != subgraph.begin())
+ while (it != subgraph.beginIConnectable())
{
--it;
- Layer& base = **it;
+ Layer& base = *(PolymorphicDowncast<Layer*>(*it));
// Fuse activation into previous layer if supported by backend
if ((base.GetType() == LayerType::DepthwiseConvolution2d || base.GetType() == LayerType::Convolution2d
@@ -498,9 +498,9 @@ OptimizationViews ClBackend::OptimizeSubgraphView(const SubgraphView& subgraph,
if (!reduceDescriptor.m_vAxis.empty() && reduceDescriptor.m_vAxis.size() > 1)
{
// Add new layers to the graph and connect them.
- std::vector<Layer*> layers = ChainReduceLayers<ReduceLayer>(optimizationViews,
- baseLayer,
- reduceDescriptor);
+ std::vector<IConnectableLayer*> layers = ChainReduceLayers<ReduceLayer>(optimizationViews,
+ baseLayer,
+ reduceDescriptor);
// Replace existing baselayer with new subgraph.
ReplaceLayers<ReduceLayer>(optimizationViews, baseLayer, layers);
diff --git a/src/backends/neon/NeonBackend.cpp b/src/backends/neon/NeonBackend.cpp
index aa5ba03075..54af14e30b 100644
--- a/src/backends/neon/NeonBackend.cpp
+++ b/src/backends/neon/NeonBackend.cpp
@@ -132,21 +132,21 @@ OptimizationViews NeonBackend::OptimizeSubgraphView(const SubgraphView& subgraph
{
OptimizationViews optimizationViews;
- auto it = subgraph.end();
+ auto it = subgraph.endIConnectable();
std::map<LayerGuid, Layer*> untouched;
- while (it != subgraph.begin())
+ while (it != subgraph.beginIConnectable())
{
--it;
- Layer& base = **it;
+ Layer& base = *(PolymorphicDowncast<Layer*>(*it));
untouched.insert({base.GetGuid(), &base});
}
- it = subgraph.end();
- while (it != subgraph.begin())
+ it = subgraph.endIConnectable();
+ while (it != subgraph.beginIConnectable())
{
--it;
- Layer& base = **it;
+ Layer& base = *(PolymorphicDowncast<Layer*>(*it));
// Fuse activation into previous layer if supported by backend
if ((base.GetType() == LayerType::DepthwiseConvolution2d || base.GetType() == LayerType::Convolution2d
@@ -390,9 +390,9 @@ OptimizationViews NeonBackend::OptimizeSubgraphView(const SubgraphView& subgraph
if (!reduceDescriptor.m_vAxis.empty() && reduceDescriptor.m_vAxis.size() > 1)
{
// Add new layers to the graph and connect them.
- std::vector<Layer*> layers = ChainReduceLayers<ReduceLayer>(optimizationViews,
- baseLayer,
- reduceDescriptor);
+ std::vector<IConnectableLayer*> layers = ChainReduceLayers<ReduceLayer>(optimizationViews,
+ baseLayer,
+ reduceDescriptor);
// Replace existing baselayer with new subgraph.
ReplaceLayers<ReduceLayer>(optimizationViews, baseLayer, layers);