From 3464ba127b83cd36d65cdc7ee9f5dd7b3715a18e Mon Sep 17 00:00:00 2001 From: Cathal Corbett Date: Fri, 4 Mar 2022 11:36:39 +0000 Subject: IVGCVSW-6772 Eliminate armnn/src/backends/backendsCommon/test/MockBackend.hpp Signed-off-by: Cathal Corbett Change-Id: Ie99fe9786eb5e30585f437d0c6362c73688148db --- src/armnnTestUtils/MockBackend.cpp | 251 ++++++++++++++++++++++++++++++++++++- 1 file changed, 246 insertions(+), 5 deletions(-) (limited to 'src/armnnTestUtils/MockBackend.cpp') diff --git a/src/armnnTestUtils/MockBackend.cpp b/src/armnnTestUtils/MockBackend.cpp index 29996bfd26..ac7f7c7fef 100644 --- a/src/armnnTestUtils/MockBackend.cpp +++ b/src/armnnTestUtils/MockBackend.cpp @@ -3,18 +3,17 @@ // SPDX-License-Identifier: MIT // +#include #include #include #include +#include +#include +#include namespace armnn { -constexpr const char* MockBackendId() -{ - return "CpuMock"; -} - const BackendId& MockBackend::GetIdStatic() { static const BackendId s_Id{MockBackendId()}; @@ -58,4 +57,246 @@ std::unique_ptr MockWorkloadFactory::CreateWorkload(LayerType type, } } +bool IsLayerSupported(const armnn::Layer* layer) +{ + ARMNN_ASSERT(layer != nullptr); + + armnn::LayerType layerType = layer->GetType(); + switch (layerType) + { + case armnn::LayerType::Input: + case armnn::LayerType::Output: + case armnn::LayerType::Addition: + case armnn::LayerType::Convolution2d: + // Layer supported + return true; + default: + // Layer unsupported + return false; + } +} + +bool IsLayerSupported(const armnn::Layer& layer) +{ + return IsLayerSupported(&layer); +} + +bool IsLayerOptimizable(const armnn::Layer* layer) +{ + ARMNN_ASSERT(layer != nullptr); + + // A Layer is not optimizable if its name contains "unoptimizable" + const std::string layerName(layer->GetName()); + bool optimizable = layerName.find("unoptimizable") == std::string::npos; + + return optimizable; +} + +bool IsLayerOptimizable(const armnn::Layer& layer) +{ + return IsLayerOptimizable(&layer); +} + +} // Anonymous namespace + +namespace armnn +{ + +MockBackendInitialiser::MockBackendInitialiser() +{ + BackendRegistryInstance().Register(MockBackend::GetIdStatic(), + []() + { + return IBackendInternalUniquePtr(new MockBackend); + }); +} + +MockBackendInitialiser::~MockBackendInitialiser() +{ + try + { + BackendRegistryInstance().Deregister(MockBackend::GetIdStatic()); + } + catch (...) + { + std::cerr << "could not deregister mock backend" << std::endl; + } +} + +IBackendInternal::IWorkloadFactoryPtr MockBackend::CreateWorkloadFactory( + const IBackendInternal::IMemoryManagerSharedPtr& /*memoryManager*/) const +{ + return IWorkloadFactoryPtr{}; +} + +IBackendInternal::IBackendContextPtr MockBackend::CreateBackendContext(const IRuntime::CreationOptions&) const +{ + return IBackendContextPtr{}; +} + +IBackendInternal::IBackendProfilingContextPtr MockBackend::CreateBackendProfilingContext( + const IRuntime::CreationOptions& options, IBackendProfilingPtr& backendProfiling) +{ + IgnoreUnused(options); + std::shared_ptr context = + std::make_shared(backendProfiling); + MockBackendProfilingService::Instance().SetProfilingContextPtr(context); + return context; +} + +IBackendInternal::IMemoryManagerUniquePtr MockBackend::CreateMemoryManager() const +{ + return IMemoryManagerUniquePtr{}; +} + +IBackendInternal::ILayerSupportSharedPtr MockBackend::GetLayerSupport() const +{ + static ILayerSupportSharedPtr layerSupport{new MockLayerSupport}; + return layerSupport; +} + +OptimizationViews MockBackend::OptimizeSubgraphView(const SubgraphView& subgraph) const +{ + // Prepare the optimization views + OptimizationViews optimizationViews; + + // Get the layers of the input sub-graph + const SubgraphView::IConnectableLayers& subgraphLayers = subgraph.GetIConnectableLayers(); + + // Parse the layers + SubgraphView::IConnectableLayers supportedLayers; + SubgraphView::IConnectableLayers unsupportedLayers; + SubgraphView::IConnectableLayers untouchedLayers; + std::for_each(subgraphLayers.begin(), + subgraphLayers.end(), + [&](IConnectableLayer* layer) + { + bool supported = IsLayerSupported(PolymorphicDowncast(layer)); + if (supported) + { + // Layer supported, check if it's optimizable + bool optimizable = IsLayerOptimizable(PolymorphicDowncast(layer)); + if (optimizable) + { + // Layer fully supported + supportedLayers.push_back(layer); + } + else + { + // Layer supported but not optimizable + untouchedLayers.push_back(layer); + } + } + else + { + // Layer unsupported + unsupportedLayers.push_back(layer); + } + }); + + // Check if there are supported layers + if (!supportedLayers.empty()) + { + // Select the layers that are neither inputs or outputs, but that are optimizable + auto supportedSubgraphSelector = [](const Layer& layer) + { + return layer.GetType() != LayerType::Input && + layer.GetType() != LayerType::Output && + IsLayerSupported(layer) && + IsLayerOptimizable(layer); + }; + + // Apply the subgraph selector to the supported layers to group them into sub-graphs were appropriate + SubgraphView mutableSubgraph(subgraph); + SubgraphViewSelector::Subgraphs supportedSubgraphs = + SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, supportedSubgraphSelector); + + // Create a substitution pair for each supported sub-graph + std::for_each(supportedSubgraphs.begin(), + supportedSubgraphs.end(), + [&optimizationViews](const SubgraphView::SubgraphViewPtr& supportedSubgraph) + { + ARMNN_ASSERT(supportedSubgraph != nullptr); + + CompiledBlobPtr blobPtr; + BackendId backend = MockBackendId(); + + IConnectableLayer* preCompiledLayer = + optimizationViews.GetINetwork()->AddPrecompiledLayer( + PreCompiledDescriptor(supportedSubgraph->GetNumInputSlots(), + supportedSubgraph->GetNumOutputSlots()), + std::move(blobPtr), + backend, + nullptr); + + SubgraphView substitutionSubgraph(*supportedSubgraph); + SubgraphView replacementSubgraph(preCompiledLayer); + + optimizationViews.AddSubstitution({ substitutionSubgraph, replacementSubgraph }); + }); + } + + // Check if there are unsupported layers + if (!unsupportedLayers.empty()) + { + // Select the layers that are neither inputs or outputs, and are not optimizable + auto unsupportedSubgraphSelector = [](const Layer& layer) + { + return layer.GetType() != LayerType::Input && + layer.GetType() != LayerType::Output && + !IsLayerSupported(layer); + }; + + // Apply the subgraph selector to the unsupported layers to group them into sub-graphs were appropriate + SubgraphView mutableSubgraph(subgraph); + SubgraphViewSelector::Subgraphs unsupportedSubgraphs = + SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, unsupportedSubgraphSelector); + + // Add each unsupported sub-graph to the list of failed sub-graphs in the optimizization views + std::for_each(unsupportedSubgraphs.begin(), + unsupportedSubgraphs.end(), + [&optimizationViews](const SubgraphView::SubgraphViewPtr& unsupportedSubgraph) + { + ARMNN_ASSERT(unsupportedSubgraph != nullptr); + + optimizationViews.AddFailedSubgraph(SubgraphView(*unsupportedSubgraph)); + }); + } + + // Check if there are untouched layers + if (!untouchedLayers.empty()) + { + // Select the layers that are neither inputs or outputs, that are supported but that and are not optimizable + auto untouchedSubgraphSelector = [](const Layer& layer) + { + return layer.GetType() != LayerType::Input && + layer.GetType() != LayerType::Output && + IsLayerSupported(layer) && + !IsLayerOptimizable(layer); + }; + + // Apply the subgraph selector to the untouched layers to group them into sub-graphs were appropriate + SubgraphView mutableSubgraph(subgraph); + SubgraphViewSelector::Subgraphs untouchedSubgraphs = + SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, untouchedSubgraphSelector); + + // Add each untouched sub-graph to the list of untouched sub-graphs in the optimizization views + std::for_each(untouchedSubgraphs.begin(), + untouchedSubgraphs.end(), + [&optimizationViews](const SubgraphView::SubgraphViewPtr& untouchedSubgraph) + { + ARMNN_ASSERT(untouchedSubgraph != nullptr); + + optimizationViews.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph)); + }); + } + + return optimizationViews; +} + +std::unique_ptr MockBackend::GetDefaultAllocator() const +{ + return std::make_unique(); +} + } // namespace armnn \ No newline at end of file -- cgit v1.2.1