From 867eba59ffd2276086a14f7b2632b390c94392d3 Mon Sep 17 00:00:00 2001 From: Narumol Prangnawarat Date: Mon, 3 Feb 2020 12:29:56 +0000 Subject: IVGCVSW-4399 Create Sample Dynamic backend * Move IWorkload and WorkloadInfo to include/armnn/backends * Add simple sample dynamic backend with addition workload * Add sample example to run dynamic backend * Unit tests Signed-off-by: Narumol Prangnawarat Change-Id: I0753ce35b8e8a6223a1471388b49246d82438a44 --- .../backendsCommon/test/DynamicBackendTests.cpp | 5 + .../backendsCommon/test/DynamicBackendTests.hpp | 121 ++++++++++++++++++++- 2 files changed, 125 insertions(+), 1 deletion(-) (limited to 'src/backends/backendsCommon/test') diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.cpp b/src/backends/backendsCommon/test/DynamicBackendTests.cpp index 40e063d8c4..bb1a5cda6c 100644 --- a/src/backends/backendsCommon/test/DynamicBackendTests.cpp +++ b/src/backends/backendsCommon/test/DynamicBackendTests.cpp @@ -71,4 +71,9 @@ ARMNN_SIMPLE_TEST_CASE(CreateReferenceDynamicBackend, CreateReferenceDynamicBack #endif +#if defined(SAMPLE_DYNAMIC_BACKEND_ENABLED) +ARMNN_SIMPLE_TEST_CASE(CreateSampleDynamicBackend, CreateSampleDynamicBackendTestImpl); +ARMNN_SIMPLE_TEST_CASE(SampleDynamicBackendEndToEnd, SampleDynamicBackendEndToEndTestImpl); +#endif + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.hpp b/src/backends/backendsCommon/test/DynamicBackendTests.hpp index 4238ef6f7d..1276776a4d 100644 --- a/src/backends/backendsCommon/test/DynamicBackendTests.hpp +++ b/src/backends/backendsCommon/test/DynamicBackendTests.hpp @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -1438,3 +1437,123 @@ void CreateReferenceDynamicBackendTestImpl() } #endif + +#if defined(SAMPLE_DYNAMIC_BACKEND_ENABLED) +void CreateSampleDynamicBackendTestImpl() +{ + using namespace armnn; + + // Using the path override in CreationOptions to load the reference dynamic backend + IRuntime::CreationOptions creationOptions; + IRuntimePtr runtime = IRuntime::Create(creationOptions); + + const BackendRegistry& backendRegistry = BackendRegistryInstance(); + BOOST_TEST(backendRegistry.Size() >= 1); + + BackendIdSet backendIds = backendRegistry.GetBackendIds(); + BOOST_TEST((backendIds.find("SampleDynamic") != backendIds.end())); + + const DeviceSpec& deviceSpec = *boost::polymorphic_downcast(&runtime->GetDeviceSpec()); + BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends(); + BOOST_TEST(supportedBackendIds.size()>= 1); + BOOST_TEST((supportedBackendIds.find("SampleDynamic") != supportedBackendIds.end())); + + // Get the factory function + auto sampleDynamicBackendFactoryFunction = backendRegistry.GetFactory("SampleDynamic"); + BOOST_TEST((sampleDynamicBackendFactoryFunction != nullptr)); + + // Use the factory function to create an instance of the dynamic backend + IBackendInternalUniquePtr sampleDynamicBackend = sampleDynamicBackendFactoryFunction(); + BOOST_TEST((sampleDynamicBackend != nullptr)); + BOOST_TEST((sampleDynamicBackend->GetId() == "SampleDynamic")); + + // Test the backend instance by querying the layer support + IBackendInternal::ILayerSupportSharedPtr sampleLayerSupport = sampleDynamicBackend->GetLayerSupport(); + BOOST_TEST((sampleLayerSupport != nullptr)); + + TensorShape inputShape { 1, 16, 16, 16 }; + TensorShape outputShape{ 1, 16, 16, 16 }; + TensorShape weightShape{ 16, 1, 1, 16 }; + TensorInfo inputInfo (inputShape, DataType::Float32); + TensorInfo outputInfo(outputShape, DataType::Float32); + TensorInfo weightInfo(weightShape, DataType::Float32); + Convolution2dDescriptor convolution2dDescriptor; + bool sampleConvolution2dSupported = + sampleLayerSupport->IsConvolution2dSupported(inputInfo, + outputInfo, + convolution2dDescriptor, + weightInfo, + EmptyOptional()); + BOOST_TEST(!sampleConvolution2dSupported); + + // Test the backend instance by creating a workload + IBackendInternal::IWorkloadFactoryPtr sampleWorkloadFactory = sampleDynamicBackend->CreateWorkloadFactory(); + BOOST_TEST((sampleWorkloadFactory != nullptr)); + + // Create dummy settings for the workload + AdditionQueueDescriptor additionQueueDescriptor; + WorkloadInfo workloadInfo + { + { inputInfo, inputInfo }, + { outputInfo } + }; + + // Create a addition workload + auto workload = sampleWorkloadFactory->CreateAddition(additionQueueDescriptor, workloadInfo); + BOOST_TEST((workload != nullptr)); +} + +void SampleDynamicBackendEndToEndTestImpl() +{ + using namespace armnn; + using namespace boost::filesystem; + // Create runtime in which test will run + IRuntime::CreationOptions options; + IRuntimePtr runtime(IRuntime::Create(options)); + + // Builds up the structure of the network. + INetworkPtr net(INetwork::Create()); + + IConnectableLayer* input0 = net->AddInputLayer(0); + IConnectableLayer* input1 = net->AddInputLayer(1); + IConnectableLayer* add = net->AddAdditionLayer(); + IConnectableLayer* output = net->AddOutputLayer(0); + + input0->GetOutputSlot(0).Connect(add->GetInputSlot(0)); + input1->GetOutputSlot(0).Connect(add->GetInputSlot(1)); + add->GetOutputSlot(0).Connect(output->GetInputSlot(0)); + + TensorInfo tensorInfo(TensorShape({2, 1}), DataType::Float32); + input0->GetOutputSlot(0).SetTensorInfo(tensorInfo); + input1->GetOutputSlot(0).SetTensorInfo(tensorInfo); + add->GetOutputSlot(0).SetTensorInfo(tensorInfo); + + // optimize the network + IOptimizedNetworkPtr optNet = Optimize(*net, {"SampleDynamic"}, runtime->GetDeviceSpec()); + + // Loads it into the runtime. + NetworkId netId; + runtime->LoadNetwork(netId, std::move(optNet)); + + std::vector input0Data{ 5.0f, 3.0f }; + std::vector input1Data{ 10.0f, 8.0f }; + std::vector expectedOutputData{ 15.0f, 11.0f }; + std::vector outputData(2); + + InputTensors inputTensors + { + {0,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), input0Data.data())}, + {1,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), input1Data.data())} + }; + OutputTensors outputTensors + { + {0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())} + }; + + // Does the inference. + runtime->EnqueueWorkload(netId, inputTensors, outputTensors); + + // Checks the results. + BOOST_TEST(outputData == expectedOutputData); +} +#endif -- cgit v1.2.1