From 146b2e15895aeedc58a8f5fcf50a7837ba9bf085 Mon Sep 17 00:00:00 2001 From: Jan Eilers Date: Fri, 16 Aug 2019 10:45:30 +0100 Subject: IVGCVSW-3605 Add direct compatibility between Cl and Neon backends * Adds compatibility between Cl and Neon * Adds related unit test Signed-off-by: Jan Eilers Signed-off-by: Mike Kelly Change-Id: Iaa454ea2a6392c89c0a83836c3156d4ddb354879 --- src/backends/backendsCommon/test/CMakeLists.txt | 5 + .../backendsCommon/test/CompatibilityTests.cpp | 117 +++++++++++++++++++++ src/backends/neon/NeonBackend.cpp | 3 +- 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/backends/backendsCommon/test/CompatibilityTests.cpp (limited to 'src/backends') diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index d6f8a6f20b..293e5b5103 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -66,6 +66,11 @@ if (ARMCOMPUTEREF) ) endif() +if(ARMCOMPUTENEON AND ARMCOMPUTECL) + list(APPEND armnnBackendsCommonUnitTests_sources + CompatibilityTests.cpp) +endif() + add_library(armnnBackendsCommonUnitTests OBJECT ${armnnBackendsCommonUnitTests_sources}) target_include_directories(armnnBackendsCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn) target_include_directories(armnnBackendsCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils) diff --git a/src/backends/backendsCommon/test/CompatibilityTests.cpp b/src/backends/backendsCommon/test/CompatibilityTests.cpp new file mode 100644 index 0000000000..599c9842b1 --- /dev/null +++ b/src/backends/backendsCommon/test/CompatibilityTests.cpp @@ -0,0 +1,117 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include + +#include +#include + +#include + +#include +#include + +using namespace armnn; + +BOOST_AUTO_TEST_SUITE(BackendsCompatibility) + +BOOST_AUTO_TEST_CASE(Neon_Cl_DirectCompatibility_Test) +{ + auto neonBackend = std::make_unique(); + auto clBackend = std::make_unique(); + + TensorHandleFactoryRegistry registry; + neonBackend->RegisterTensorHandleFactories(registry); + clBackend->RegisterTensorHandleFactories(registry); + + const BackendId& neonBackendId = neonBackend->GetId(); + const BackendId& clBackendId = clBackend->GetId(); + + BackendsMap backends; + backends[neonBackendId] = std::move(neonBackend); + backends[clBackendId] = std::move(clBackend); + + armnn::Graph graph; + + armnn::InputLayer* const inputLayer = graph.AddLayer(0, "input"); + + inputLayer->SetBackendId(neonBackendId); + + armnn::SoftmaxDescriptor smDesc; + armnn::SoftmaxLayer* const softmaxLayer1 = graph.AddLayer(smDesc, "softmax1"); + softmaxLayer1->SetBackendId(clBackendId); + + armnn::SoftmaxLayer* const softmaxLayer2 = graph.AddLayer(smDesc, "softmax2"); + softmaxLayer2->SetBackendId(neonBackendId); + + armnn::SoftmaxLayer* const softmaxLayer3 = graph.AddLayer(smDesc, "softmax3"); + softmaxLayer3->SetBackendId(clBackendId); + + armnn::SoftmaxLayer* const softmaxLayer4 = graph.AddLayer(smDesc, "softmax4"); + softmaxLayer4->SetBackendId(neonBackendId); + + armnn::OutputLayer* const outputLayer = graph.AddLayer(0, "output"); + outputLayer->SetBackendId(clBackendId); + + inputLayer->GetOutputSlot(0).Connect(softmaxLayer1->GetInputSlot(0)); + softmaxLayer1->GetOutputSlot(0).Connect(softmaxLayer2->GetInputSlot(0)); + softmaxLayer2->GetOutputSlot(0).Connect(softmaxLayer3->GetInputSlot(0)); + softmaxLayer3->GetOutputSlot(0).Connect(softmaxLayer4->GetInputSlot(0)); + softmaxLayer4->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); + + graph.TopologicalSort(); + + std::vector errors; + auto result = SelectTensorHandleStrategy(graph, backends, registry, errors); + + BOOST_TEST(result.m_Error == false); + BOOST_TEST(result.m_Warning == false); + + OutputSlot& inputLayerOut = inputLayer->GetOutputSlot(0); + OutputSlot& softmaxLayer1Out = softmaxLayer1->GetOutputSlot(0); + OutputSlot& softmaxLayer2Out = softmaxLayer2->GetOutputSlot(0); + OutputSlot& softmaxLayer3Out = softmaxLayer3->GetOutputSlot(0); + OutputSlot& softmaxLayer4Out = softmaxLayer4->GetOutputSlot(0); + + // Check that the correct factory was selected + BOOST_TEST(inputLayerOut.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory"); + BOOST_TEST(softmaxLayer1Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory"); + BOOST_TEST(softmaxLayer2Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory"); + BOOST_TEST(softmaxLayer3Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory"); + BOOST_TEST(softmaxLayer4Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory"); + + // Check that the correct strategy was selected + BOOST_TEST((inputLayerOut.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility)); + BOOST_TEST((softmaxLayer1Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility)); + BOOST_TEST((softmaxLayer2Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility)); + BOOST_TEST((softmaxLayer3Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility)); + BOOST_TEST((softmaxLayer4Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility)); + + graph.AddCompatibilityLayers(backends, registry); + + // Test for copy layers + int copyCount= 0; + graph.ForEachLayer([©Count](Layer* layer) + { + if (layer->GetType() == LayerType::MemCopy) + { + copyCount++; + } + }); + BOOST_TEST(copyCount == 0); + + // Test for import layers + int importCount= 0; + graph.ForEachLayer([&importCount](Layer *layer) + { + if (layer->GetType() == LayerType::MemImport) + { + importCount++; + } + }); + BOOST_TEST(importCount == 0); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/neon/NeonBackend.cpp b/src/backends/neon/NeonBackend.cpp index 60f8ba6dab..63529c9693 100644 --- a/src/backends/neon/NeonBackend.cpp +++ b/src/backends/neon/NeonBackend.cpp @@ -82,7 +82,8 @@ OptimizationViews NeonBackend::OptimizeSubgraphView(const SubgraphView& subgraph std::vector NeonBackend::GetHandleFactoryPreferences() const { - return std::vector() = {NeonTensorHandleFactory::GetIdStatic()}; + return std::vector() = {"Arm/Neon/TensorHandleFactory", + "Arm/Cl/TensorHandleFactory"}; } void NeonBackend::RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry) -- cgit v1.2.1