IVGCVSW-6453 'Move the ArmNN Test Utils code to a physically separate directory'

* Created include/armnnTestUtils directory
* Moved Arm NN test utils files into armnnTestUtils directory

Signed-off-by: Sadik Armagan <sadik.armagan@arm.com>
Change-Id: I03ac54c645c41c52650c4c03b6a58fb1481fef5d
diff --git a/src/armnn/test/CreateWorkload.hpp b/src/armnn/test/CreateWorkload.hpp
index ea8a436..ae07253 100644
--- a/src/armnn/test/CreateWorkload.hpp
+++ b/src/armnn/test/CreateWorkload.hpp
@@ -2,2315 +2,8 @@
 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
-#pragma once
 
-#include "TestUtils.hpp"
-
-#include <Graph.hpp>
-#include <Network.hpp>
-#include <ResolveType.hpp>
-
-#include <armnnUtils/DataLayoutIndexed.hpp>
-#include <armnn/utility/Assert.hpp>
-#include <armnn/utility/IgnoreUnused.hpp>
-#include <armnn/utility/PolymorphicDowncast.hpp>
-
-#include <backendsCommon/TensorHandle.hpp>
-#include <backendsCommon/WorkloadData.hpp>
-#include <backendsCommon/WorkloadFactory.hpp>
-
-#include <doctest/doctest.h>
-
-#include <utility>
-
-using namespace armnn;
-
-namespace
-{
-
-using namespace std;
-
-// Calls CreateWorkload for a layer, and checks the returned pointer is of the correct type.
-template<typename Workload>
-std::unique_ptr<Workload> MakeAndCheckWorkload(Layer& layer,
-                                               const IWorkloadFactory& factory,
-                                               const ModelOptions& modelOptions = {})
-{
-    std::unique_ptr<IWorkload> workload = layer.CreateWorkload(factory);
-    CHECK_MESSAGE(workload.get() == PolymorphicDowncast<Workload*>(workload.get()),
-               "Cannot convert to derived class");
-    std::string reasonIfUnsupported;
-    layer.SetBackendId(factory.GetBackendId());
-    CHECK(factory.IsLayerSupported(layer, layer.GetDataType(), reasonIfUnsupported, modelOptions));
-    return std::unique_ptr<Workload>(static_cast<Workload*>(workload.release()));
-}
-
-// Helper function to create tensor handlers for workloads, assuming they all use the same factory.
-void CreateTensorHandles(armnn::Graph& graph,
-                         armnn::IWorkloadFactory& factory)
-{
-    TensorHandleFactoryRegistry tmpRegistry;
-    for (auto&& layer : graph.TopologicalSort())
-    {
-        layer->CreateTensorHandles(tmpRegistry, factory);
-    }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-// The following functions are called by backendsCommon/test/CreateWorkload*.cpp
-// They build very simple graphs, and then create a workload.
-// Some checks are performed on the workload to ensure parameters have been passed correctly.
-// They return the created workloads so that backend-specific checks can be performed.
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-template <typename ActivationWorkload, armnn::DataType DataType>
-std::unique_ptr<ActivationWorkload> CreateActivationWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                 armnn::Graph&            graph)
-{
-    // Creates the layer we're testing.
-    ActivationDescriptor layerDesc;
-    layerDesc.m_Function = ActivationFunction::Abs;
-    layerDesc.m_A        = 3.5f;
-    layerDesc.m_B        = -10.0f;
-
-    ActivationLayer* const layer = graph.AddLayer<ActivationLayer>(layerDesc, "layer");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo({1, 1}, DataType);
-
-    Connect(input, layer, tensorInfo);
-    Connect(layer, output, tensorInfo);
-
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<ActivationWorkload>(*layer, factory);
-
-    ActivationQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK(queueDescriptor.m_Parameters.m_A == 3.5f);
-    CHECK(queueDescriptor.m_Parameters.m_B == -10.0f);
-    CHECK((queueDescriptor.m_Parameters.m_Function == ActivationFunction::Abs));
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename WorkloadType,
-          typename DescriptorType,
-          typename LayerType,
-          armnn::DataType DataType>
-std::unique_ptr<WorkloadType> CreateElementwiseWorkloadTest(armnn::IWorkloadFactory & factory,
-                                                            armnn::Graph & graph)
-{
-    // Creates the layer we're testing.
-    Layer* const layer = graph.AddLayer<LayerType>("layer");
-
-    // Creates extra layers.
-    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
-    Layer* const input2 = graph.AddLayer<InputLayer>(2, "input2");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo({2, 3}, DataType);
-    Connect(input1, layer, tensorInfo, 0, 0);
-    Connect(input2, layer, tensorInfo, 0, 1);
-    Connect(layer, output, tensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
-
-    DescriptorType queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 2);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template<typename WorkloadType,
-         typename DescriptorType,
-         armnn::DataType DataType>
-std::unique_ptr<WorkloadType> CreateSubtractionWithBlobWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                    armnn::Graph& graph)
-{
-    // Creates the layer we're testing.
-    SubtractionLayer* const layer = graph.AddLayer<SubtractionLayer>("layer");
-
-    auto activationDesc = std::make_shared<ActivationDescriptor>();
-    activationDesc->m_A        = 10.0f;
-    activationDesc->m_B        = 5.0f;
-    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
-
-    layer->SetAdditionalInfoForObject(activationDesc);
-
-    // Creates extra layers.
-    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
-    Layer* const input2 = graph.AddLayer<InputLayer>(2, "input2");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo({2, 3}, DataType);
-    Connect(input1, layer, tensorInfo, 0, 0);
-    Connect(input2, layer, tensorInfo, 0, 1);
-    Connect(layer, output, tensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Check that the additional information can be queried from the layer
-    std::shared_ptr<ActivationDescriptor>
-        activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
-
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
-
-    DescriptorType queueDescriptor = workload->GetData();
-
-    const ActivationDescriptor* queueDescBlobPtr =
-        queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
-    IgnoreUnused(queueDescBlobPtr);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    CHECK(queueDescriptor.m_Inputs.size() == 2);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    return workload;
-}
-
-template<typename WorkloadType,
-         typename DescriptorType,
-         armnn::DataType DataType>
-std::unique_ptr<WorkloadType> CreateMultiplicationWithBlobWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                       armnn::Graph& graph)
-{
-    // Creates the layer we're testing.
-    MultiplicationLayer* const layer = graph.AddLayer<MultiplicationLayer>("layer");
-
-    auto activationDesc = std::make_shared<ActivationDescriptor>();
-    activationDesc->m_A        = 10.0f;
-    activationDesc->m_B        = 5.0f;
-    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
-
-    layer->SetAdditionalInfoForObject(activationDesc);
-
-    // Creates extra layers.
-    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
-    Layer* const input2 = graph.AddLayer<InputLayer>(2, "input2");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo({2, 3}, DataType);
-    Connect(input1, layer, tensorInfo, 0, 0);
-    Connect(input2, layer, tensorInfo, 0, 1);
-    Connect(layer, output, tensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Check that the additional information can be queried from the layer
-    std::shared_ptr<ActivationDescriptor>
-        activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
-
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
-
-    DescriptorType queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 2);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    const ActivationDescriptor* queueDescBlobPtr =
-        queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
-    IgnoreUnused(queueDescBlobPtr);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    return workload;// Returns so we can do extra, backend-specific tests.
-}
-
-template<typename WorkloadType,
-         typename DescriptorType,
-         armnn::DataType DataType>
-std::unique_ptr<WorkloadType> CreateAdditionWithBlobWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                 armnn::Graph& graph)
-{
-    // Creates the layer we're testing.
-    AdditionLayer* const layer = graph.AddLayer<AdditionLayer>("layer");
-
-    auto activationDesc = std::make_shared<ActivationDescriptor>();
-    activationDesc->m_A        = 10.0f;
-    activationDesc->m_B        = 5.0f;
-    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
-
-    layer->SetAdditionalInfoForObject(activationDesc);
-
-    // Creates extra layers.
-    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
-    Layer* const input2 = graph.AddLayer<InputLayer>(2, "input2");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo({2, 3}, DataType);
-    Connect(input1, layer, tensorInfo, 0, 0);
-    Connect(input2, layer, tensorInfo, 0, 1);
-    Connect(layer, output, tensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Check that the additional information can be queried from the layer
-    std::shared_ptr<ActivationDescriptor>
-        activationDescPtr = layer->template GetAdditionalInformation<ActivationDescriptor>();
-
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
-
-    DescriptorType queueDescriptor = workload->GetData();
-    const ActivationDescriptor* queueDescBlobPtr =
-        queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
-    IgnoreUnused(queueDescBlobPtr);
-    CHECK(queueDescriptor.m_Inputs.size() == 2);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    return workload;
-}
-
-template <typename WorkloadType,
-          typename DescriptorType,
-          armnn::DataType DataType>
-std::unique_ptr<WorkloadType> CreateElementwiseUnaryWorkloadTest(armnn::IWorkloadFactory & factory,
-                                                                 armnn::Graph & graph,
-                                                                 armnn::UnaryOperation op)
-{
-    ElementwiseUnaryDescriptor desc = ElementwiseUnaryDescriptor(op);
-    Layer* const layer = graph.AddLayer<armnn::ElementwiseUnaryLayer>(desc, "layer");
-
-    Layer* const input  = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    armnn::TensorInfo tensorInfo({ 2, 3 }, DataType);
-    Connect(input, layer, tensorInfo, 0, 0);
-    Connect(layer, output, tensorInfo, 0, 0);
-    CreateTensorHandles(graph, factory);
-
-    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
-    DescriptorType queueDescriptor = workload->GetData();
-
-    CHECK(queueDescriptor.m_Inputs.size()  == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    return workload;
-}
-
-template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
-std::unique_ptr<BatchNormalizationWorkloadType> CreateBatchNormalizationWorkloadTest(
-    armnn::IWorkloadFactory& factory, armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW)
-{
-    TensorShape tensorShape;
-    switch (dataLayout)
-    {
-        case DataLayout::NHWC:
-            tensorShape = { 2, 4, 4, 3 };
-            break;
-        case DataLayout::NCHW:
-        default:
-            tensorShape = { 2, 3, 4, 4 };
-    }
-
-    // Creates the layer we're testing.
-    BatchNormalizationDescriptor layerDesc;
-    layerDesc.m_Eps = 0.05f;
-    layerDesc.m_DataLayout = dataLayout;
-
-    BatchNormalizationLayer* const layer = graph.AddLayer<BatchNormalizationLayer>(layerDesc, "layer");
-
-    armnn::TensorInfo weightInfo({3}, DataType);
-    layer->m_Mean     = std::make_unique<ScopedTensorHandle>(weightInfo);
-    layer->m_Variance = std::make_unique<ScopedTensorHandle>(weightInfo);
-    layer->m_Beta     = std::make_unique<ScopedTensorHandle>(weightInfo);
-    layer->m_Gamma    = std::make_unique<ScopedTensorHandle>(weightInfo);
-    layer->m_Mean->Allocate();
-    layer->m_Variance->Allocate();
-    layer->m_Beta->Allocate();
-    layer->m_Gamma->Allocate();
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo(tensorShape, DataType);
-    Connect(input, layer, tensorInfo);
-    Connect(layer, output, tensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<BatchNormalizationWorkloadType>(*layer, factory);
-    BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_Eps == 0.05f);
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK((queueDescriptor.m_Mean->GetTensorInfo() == TensorInfo({3}, DataType)));
-    CHECK((queueDescriptor.m_Variance->GetTensorInfo() == TensorInfo({3}, DataType)));
-    CHECK((queueDescriptor.m_Gamma->GetTensorInfo() == TensorInfo({3}, DataType)));
-    CHECK((queueDescriptor.m_Beta->GetTensorInfo() == TensorInfo({3}, DataType)));
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
-std::unique_ptr<BatchNormalizationWorkloadType> CreateBatchNormalizationWithBlobWorkloadTest(
-    armnn::IWorkloadFactory& factory, armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW)
-{
-    TensorShape tensorShape;
-    switch (dataLayout)
-    {
-        case DataLayout::NHWC:
-            tensorShape = { 2, 4, 4, 3 };
-            break;
-        case DataLayout::NCHW:
-        default:
-            tensorShape = { 2, 3, 4, 4 };
-    }
-
-    // Creates the layer we're testing.
-    BatchNormalizationDescriptor layerDesc;
-    layerDesc.m_Eps = 0.05f;
-    layerDesc.m_DataLayout = dataLayout;
-
-    BatchNormalizationLayer* const layer = graph.AddLayer<BatchNormalizationLayer>(layerDesc, "layer");
-
-    armnn::TensorInfo weightInfo({3}, DataType);
-    layer->m_Mean     = std::make_unique<ScopedTensorHandle>(weightInfo);
-    layer->m_Variance = std::make_unique<ScopedTensorHandle>(weightInfo);
-    layer->m_Beta     = std::make_unique<ScopedTensorHandle>(weightInfo);
-    layer->m_Gamma    = std::make_unique<ScopedTensorHandle>(weightInfo);
-    layer->m_Mean->Allocate();
-    layer->m_Variance->Allocate();
-    layer->m_Beta->Allocate();
-    layer->m_Gamma->Allocate();
-
-    auto activationDesc = std::make_shared<ActivationDescriptor>();
-    activationDesc->m_A        = 10.0f;
-    activationDesc->m_B        = 5.0f;
-    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
-
-    layer->SetAdditionalInfoForObject(activationDesc);
-
-    // Check that the additional information can be queried from the layer
-    std::shared_ptr<ActivationDescriptor> activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo(tensorShape, DataType);
-    Connect(input, layer, tensorInfo);
-    Connect(layer, output, tensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<BatchNormalizationWorkloadType>(*layer, factory);
-    BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
-    const ActivationDescriptor* queueDescBlobPtr = queueDescriptor.GetAdditionalInformation<ActivationDescriptor>();
-    IgnoreUnused(queueDescBlobPtr);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    CHECK(queueDescriptor.m_Parameters.m_Eps == 0.05f);
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK((queueDescriptor.m_Mean->GetTensorInfo() == TensorInfo({3}, DataType)));
-    CHECK((queueDescriptor.m_Variance->GetTensorInfo() == TensorInfo({3}, DataType)));
-    CHECK((queueDescriptor.m_Gamma->GetTensorInfo() == TensorInfo({3}, DataType)));
-    CHECK((queueDescriptor.m_Beta->GetTensorInfo() == TensorInfo({3}, DataType)));
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename Convolution2dWorkload, armnn::DataType DataType>
-std::unique_ptr<Convolution2dWorkload> CreateConvolution2dWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                       armnn::Graph&            graph,
-                                                                       DataLayout dataLayout = DataLayout::NCHW,
-                                                                       const ModelOptions& modelOptions = {})
-{
-    // Creates the layer we're testing.
-    Convolution2dDescriptor layerDesc;
-    layerDesc.m_PadLeft = 3;
-    layerDesc.m_PadRight = 3;
-    layerDesc.m_PadTop = 1;
-    layerDesc.m_PadBottom = 1;
-    layerDesc.m_StrideX = 2;
-    layerDesc.m_StrideY = 4;
-    layerDesc.m_BiasEnabled = true;
-    layerDesc.m_DataLayout = dataLayout;
-
-    Convolution2dLayer* const layer = graph.AddLayer<Convolution2dLayer>(layerDesc, "layer");
-
-    TensorShape weightShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 5, 3} : TensorShape{2, 5, 3, 3};
-    TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
-    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
-
-    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo(weightShape, DataType));
-    layer->m_Bias   = std::make_unique<ScopedTensorHandle>(TensorInfo({2}, GetBiasDataType(DataType)));
-
-    layer->m_Weight->Allocate();
-    layer->m_Bias->Allocate();
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    Connect(input, layer, TensorInfo(inputShape, DataType));
-    Connect(layer, output, TensorInfo(outputShape, DataType));
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
-
-    Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
-    CHECK(queueDescriptor.m_Parameters.m_StrideY == 4);
-    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 3);
-    CHECK(queueDescriptor.m_Parameters.m_PadRight == 3);
-    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
-    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled);
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType)));
-    CHECK((queueDescriptor.m_Bias->GetTensorInfo() ==
-        TensorInfo({2}, GetBiasDataType(DataType))));
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template<typename Convolution2dWorkload, armnn::DataType DataType>
-std::unique_ptr<Convolution2dWorkload> CreateConvolution2dFusedActivationWithBlobWorkloadTest(
-    armnn::IWorkloadFactory& factory,
-    armnn::Graph& graph,
-    DataLayout dataLayout = DataLayout::NCHW,
-    const ModelOptions& modelOptions = {})
-{
-    // Creates the layer we're testing.
-    Convolution2dDescriptor layerDesc;
-    layerDesc.m_PadLeft = 3;
-    layerDesc.m_PadRight = 3;
-    layerDesc.m_PadTop = 1;
-    layerDesc.m_PadBottom = 1;
-    layerDesc.m_StrideX = 2;
-    layerDesc.m_StrideY = 4;
-    layerDesc.m_BiasEnabled = true;
-    layerDesc.m_DataLayout = dataLayout;
-
-
-    Convolution2dLayer* const layer = graph.AddLayer<Convolution2dLayer>(layerDesc, "layer");
-
-    TensorShape weightShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 5, 3} : TensorShape{2, 5, 3, 3};
-    TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
-    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
-
-    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo(weightShape, DataType));
-    layer->m_Bias   = std::make_unique<ScopedTensorHandle>(TensorInfo({2}, GetBiasDataType(DataType)));
-
-    layer->m_Weight->Allocate();
-    layer->m_Bias->Allocate();
-
-    auto activationDesc = std::make_shared<ActivationDescriptor>();
-    activationDesc->m_A        = 10.0f;
-    activationDesc->m_B        = 5.0f;
-    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
-
-    layer->SetAdditionalInfoForObject(activationDesc);
-
-    // Check that the additional information can be queried from the layer
-    std::shared_ptr<ActivationDescriptor> activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
-
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    Connect(input, layer, TensorInfo(inputShape, DataType));
-    Connect(layer, output, TensorInfo(outputShape, DataType));
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
-
-    Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
-    const ActivationDescriptor* queueDescBlobPtr = queueDescriptor.GetAdditionalInformation<ActivationDescriptor>();
-    IgnoreUnused(queueDescBlobPtr);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
-    CHECK(queueDescriptor.m_Parameters.m_StrideY == 4);
-    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 3);
-    CHECK(queueDescriptor.m_Parameters.m_PadRight == 3);
-    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
-    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled);
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType)));
-    CHECK((queueDescriptor.m_Bias->GetTensorInfo() ==
-        TensorInfo({2}, GetBiasDataType(DataType))));
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename Convolution2dWorkload, armnn::DataType DataType>
-std::unique_ptr<Convolution2dWorkload> CreateConvolution2dWorkloadFastMathTest(armnn::IWorkloadFactory& factory,
-                                                                               armnn::Graph&            graph,
-                                                                               DataLayout dataLayout = DataLayout::NCHW,
-                                                                               const ModelOptions& modelOptions = {})
-{
-    // Creates the layer we're testing.
-    Convolution2dDescriptor layerDesc;
-    layerDesc.m_PadLeft = 0;
-    layerDesc.m_PadRight = 0;
-    layerDesc.m_PadTop = 0;
-    layerDesc.m_PadBottom = 0;
-    layerDesc.m_StrideX = 1;
-    layerDesc.m_StrideY = 1;
-    layerDesc.m_BiasEnabled = false;
-    layerDesc.m_DataLayout = dataLayout;
-
-    Convolution2dLayer* const layer = graph.AddLayer<Convolution2dLayer>(layerDesc, "layer");
-
-    TensorShape weightShape = TensorShape{32, 32, 3, 3};
-    TensorShape inputShape  = TensorShape{1, 32, 149, 149};
-    TensorShape outputShape = TensorShape{1, 32, 147, 147};
-
-    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo(weightShape, DataType));
-    layer->m_Bias   = std::make_unique<ScopedTensorHandle>(TensorInfo({2}, GetBiasDataType(DataType)));
-
-    layer->m_Weight->Allocate();
-    layer->m_Bias->Allocate();
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    Connect(input, layer, TensorInfo(inputShape, DataType));
-    Connect(layer, output, TensorInfo(outputShape, DataType));
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
-
-    Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
-    CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 0);
-    CHECK(queueDescriptor.m_Parameters.m_PadRight == 0);
-    CHECK(queueDescriptor.m_Parameters.m_PadTop == 0);
-    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 0);
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType)));
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename LstmWorkload>
-std::unique_ptr<LstmWorkload> CreateLstmWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph)
-{
-    // This parameter setting is for withCifgWithPeepholeNoProjection
-    LstmDescriptor layerDesc;
-    layerDesc.m_ActivationFunc = 4;
-    layerDesc.m_ClippingThresCell = 0.0f;
-    layerDesc.m_ClippingThresProj = 0.0f;
-    layerDesc.m_CifgEnabled = true;
-    layerDesc.m_PeepholeEnabled = true;
-    layerDesc.m_ProjectionEnabled = false;
-
-    LstmLayer* const layer = graph.AddLayer<LstmLayer>(layerDesc, "layer");
-    unsigned int batchSize = 2;
-    unsigned int inputSize = 2;
-    unsigned int numUnits = 4;
-    unsigned int outputSize = 4;
-
-    layer->m_BasicParameters.m_InputToForgetWeights = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits, inputSize }, DataType::Float32));
-    layer->m_BasicParameters.m_InputToCellWeights = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits, inputSize }, DataType::Float32));
-    layer->m_BasicParameters.m_InputToOutputWeights = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits, inputSize }, DataType::Float32));
-    layer->m_BasicParameters.m_RecurrentToForgetWeights = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits, outputSize }, DataType::Float32));
-    layer->m_BasicParameters.m_RecurrentToCellWeights = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits, outputSize }, DataType::Float32));
-    layer->m_BasicParameters.m_RecurrentToOutputWeights = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits, outputSize }, DataType::Float32));
-    layer->m_BasicParameters.m_ForgetGateBias = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits }, DataType::Float32));
-    layer->m_BasicParameters.m_CellBias = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits }, DataType::Float32));
-    layer->m_BasicParameters.m_OutputGateBias = std::make_unique<ScopedTensorHandle>
-            (TensorInfo({ numUnits }, DataType::Float32));
-
-    layer->m_BasicParameters.m_InputToForgetWeights->Allocate();
-    layer->m_BasicParameters.m_InputToCellWeights->Allocate();
-    layer->m_BasicParameters.m_InputToOutputWeights->Allocate();
-    layer->m_BasicParameters.m_RecurrentToForgetWeights->Allocate();
-    layer->m_BasicParameters.m_RecurrentToCellWeights->Allocate();
-    layer->m_BasicParameters.m_RecurrentToOutputWeights->Allocate();
-    layer->m_BasicParameters.m_ForgetGateBias->Allocate();
-    layer->m_BasicParameters.m_CellBias->Allocate();
-    layer->m_BasicParameters.m_OutputGateBias->Allocate();
-
-
-    if (layerDesc.m_PeepholeEnabled)
-    {
-        layer->m_PeepholeParameters.m_CellToForgetWeights = std::make_unique<ScopedTensorHandle>
-                (TensorInfo({ numUnits }, DataType::Float32));
-        layer->m_PeepholeParameters.m_CellToOutputWeights = std::make_unique<ScopedTensorHandle>
-                (TensorInfo({ numUnits }, DataType::Float32));
-        layer->m_PeepholeParameters.m_CellToForgetWeights->Allocate();
-        layer->m_PeepholeParameters.m_CellToOutputWeights->Allocate();
-    }
-
-    // create input and output layers
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const outputStateIn = graph.AddLayer<InputLayer>(1, "outputStateIn");
-    Layer* const cellStateIn = graph.AddLayer<InputLayer>(2, "cellStateIn");
-    Layer* const scratchBuffer = graph.AddLayer<OutputLayer>(0, "scratchBuffer");
-    Layer* const outputStateOut = graph.AddLayer<OutputLayer>(1, "outputStateOut");
-    Layer* const cellStateOut = graph.AddLayer<OutputLayer>(2, "cellStateOut");
-    Layer* const output = graph.AddLayer<OutputLayer>(3, "output");
-
-    // connect up
-    armnn::TensorInfo lstmTensorInfo1({ batchSize, inputSize }, DataType::Float32);
-    armnn::TensorInfo lstmTensorInfo2({ batchSize, numUnits}, DataType::Float32);
-    armnn::TensorInfo lstmTensorInfo3({ batchSize, outputSize }, DataType::Float32);
-    armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * (layerDesc.m_CifgEnabled ? 3 : 4) },
-                                                DataType::Float32);
-    Connect(input, layer, lstmTensorInfo1, 0, 0);
-    Connect(cellStateIn, layer, lstmTensorInfo2, 0, 1);
-    Connect(outputStateIn, layer, lstmTensorInfo3, 0, 2);
-    Connect(layer, scratchBuffer, lstmTensorInfoScratchBuff, 0, 0);
-    Connect(layer, outputStateOut, lstmTensorInfo3, 1, 0);
-    Connect(layer, cellStateOut, lstmTensorInfo2, 2, 0);
-    Connect(layer, output, lstmTensorInfo3, 3, 0);
-
-    CreateTensorHandles(graph, factory);
-
-    // make the workload and check it
-    auto workload = MakeAndCheckWorkload<LstmWorkload>(*layer, factory);
-    LstmQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_ActivationFunc == 4);
-    CHECK(queueDescriptor.m_Parameters.m_ClippingThresCell == 0.0f);
-    CHECK(queueDescriptor.m_Parameters.m_ClippingThresProj == 0.0f);
-    CHECK(queueDescriptor.m_Inputs.size() == 3);
-    CHECK(queueDescriptor.m_Outputs.size() == 4);
-
-    CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == TensorInfo({ numUnits, inputSize },
-                                                                                     DataType::Float32)));
-    CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() == TensorInfo({ numUnits },
-                                                                                     DataType::Float32)));
-    CHECK((queueDescriptor.m_CellBias->GetTensorInfo() == TensorInfo({ numUnits }, DataType::Float32)));
-    return workload;
-}
-
-template <typename QuantizedLstmWorkload>
-std::unique_ptr<QuantizedLstmWorkload> CreateQuantizedLstmWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                       armnn::Graph& graph)
-{
-    auto layer = graph.AddLayer<QuantizedLstmLayer>("quantizedLstmlayer");
-    unsigned int numBatches = 2;
-    unsigned int inputSize = 2;
-    unsigned int outputSize = 4;
-
-    // Scale/Offset for input/output, cellState In/Out, weights, bias
-    float inputOutputScale = 0.0078125f;
-    int32_t inputOutputOffset = 128;
-
-    float cellStateScale = 0.00048828125f;
-    int32_t cellStateOffset = 0;
-
-    float weightsScale = 0.00408021f;
-    int32_t weightsOffset = 100;
-
-    float biasScale = 3.1876640625e-05f;
-    int32_t biasOffset = 0;
-
-    // Weights and bias tensor and quantization info
-    armnn::TensorInfo inputWeightsInfo({outputSize, inputSize},
-                                       armnn::DataType::QAsymmU8,
-                                       weightsScale,
-                                       weightsOffset);
-
-    armnn::TensorInfo recurrentWeightsInfo({outputSize, outputSize},
-                                           armnn::DataType::QAsymmU8,
-                                           weightsScale,
-                                           weightsOffset);
-
-    armnn::TensorInfo biasInfo({outputSize},
-                               armnn::DataType::Signed32,
-                               biasScale,
-                               biasOffset);
-
-    // Weights and bias
-    layer->m_QuantizedLstmParameters.m_InputToInputWeights =
-            std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
-    layer->m_QuantizedLstmParameters.m_InputToForgetWeights =
-            std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
-    layer->m_QuantizedLstmParameters.m_InputToCellWeights =
-            std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
-    layer->m_QuantizedLstmParameters.m_InputToOutputWeights =
-            std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
-
-    layer->m_QuantizedLstmParameters.m_RecurrentToInputWeights =
-            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
-    layer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights =
-            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
-    layer->m_QuantizedLstmParameters.m_RecurrentToCellWeights =
-            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
-    layer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights =
-            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
-
-    layer->m_QuantizedLstmParameters.m_InputGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
-    layer->m_QuantizedLstmParameters.m_ForgetGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
-    layer->m_QuantizedLstmParameters.m_CellBias = std::make_unique<ScopedTensorHandle>(biasInfo);
-    layer->m_QuantizedLstmParameters.m_OutputGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
-
-    // Allocate weights and bias
-    layer->m_QuantizedLstmParameters.m_InputToInputWeights->Allocate();
-    layer->m_QuantizedLstmParameters.m_InputToForgetWeights->Allocate();
-    layer->m_QuantizedLstmParameters.m_InputToCellWeights->Allocate();
-    layer->m_QuantizedLstmParameters.m_InputToOutputWeights->Allocate();
-
-    layer->m_QuantizedLstmParameters.m_RecurrentToInputWeights->Allocate();
-    layer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights->Allocate();
-    layer->m_QuantizedLstmParameters.m_RecurrentToCellWeights->Allocate();
-    layer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights->Allocate();
-
-    layer->m_QuantizedLstmParameters.m_InputGateBias->Allocate();
-    layer->m_QuantizedLstmParameters.m_ForgetGateBias->Allocate();
-    layer->m_QuantizedLstmParameters.m_CellBias->Allocate();
-    layer->m_QuantizedLstmParameters.m_OutputGateBias->Allocate();
-
-    // Create input and output layers
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const cellStateIn = graph.AddLayer<InputLayer>(1, "cellStateIn");
-    Layer* const outputStateIn = graph.AddLayer<InputLayer>(2, "outputStateIn");
-
-    Layer* const cellStateOut = graph.AddLayer<OutputLayer>(0, "cellStateOut");
-    Layer* const outputStateOut = graph.AddLayer<OutputLayer>(1, "outputStateOut");
-
-    // Input/output tensor info and quantization info
-    armnn::TensorInfo inputInfo({numBatches , inputSize},
-                                armnn::DataType::QAsymmU8,
-                                inputOutputScale,
-                                inputOutputOffset);
-
-    armnn::TensorInfo cellStateInfo({numBatches , outputSize},
-                                    armnn::DataType::QSymmS16,
-                                    cellStateScale,
-                                    cellStateOffset);
-
-    armnn::TensorInfo outputStateInfo({numBatches , outputSize},
-                                      armnn::DataType::QAsymmU8,
-                                      inputOutputScale,
-                                      inputOutputOffset);
-
-    // Connect input/output slots
-    Connect(input, layer, inputInfo, 0, 0);
-    Connect(cellStateIn, layer, cellStateInfo, 0, 1);
-    Connect(outputStateIn, layer, outputStateInfo, 0, 2);
-
-    Connect(layer, cellStateOut, cellStateInfo, 0, 0);
-    Connect(layer, outputStateOut, outputStateInfo, 1, 0);
-
-    CreateTensorHandles(graph, factory);
-
-    // Create workload and check layer support
-    auto workload = MakeAndCheckWorkload<QuantizedLstmWorkload>(*layer, factory);
-    QuantizedLstmQueueDescriptor queueDescriptor = workload->GetData();
-
-    // Validate input/output sizes
-    CHECK(queueDescriptor.m_Inputs.size() == 3);
-    CHECK(queueDescriptor.m_Outputs.size() == 2);
-
-    // Validate weight tensor info
-    CHECK((queueDescriptor.m_InputToInputWeights->GetTensorInfo() == inputWeightsInfo));
-    CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == inputWeightsInfo));
-    CHECK((queueDescriptor.m_InputToCellWeights->GetTensorInfo() == inputWeightsInfo));
-    CHECK((queueDescriptor.m_InputToOutputWeights->GetTensorInfo() == inputWeightsInfo));
-
-    CHECK((queueDescriptor.m_RecurrentToInputWeights->GetTensorInfo() == recurrentWeightsInfo));
-    CHECK((queueDescriptor.m_RecurrentToForgetWeights->GetTensorInfo() == recurrentWeightsInfo));
-    CHECK((queueDescriptor.m_RecurrentToCellWeights->GetTensorInfo() == recurrentWeightsInfo));
-    CHECK((queueDescriptor.m_RecurrentToOutputWeights->GetTensorInfo() == recurrentWeightsInfo));
-
-    CHECK((queueDescriptor.m_InputGateBias->GetTensorInfo() == biasInfo));
-    CHECK((queueDescriptor.m_ForgetGateBias->GetTensorInfo() == biasInfo));
-    CHECK((queueDescriptor.m_CellBias->GetTensorInfo() == biasInfo));
-    CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() == biasInfo));
-
-    return workload;
-}
-
-template <typename QLstmWorkload>
-std::unique_ptr<QLstmWorkload> CreateQLstmWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                       armnn::Graph& graph)
-{
-    QLstmDescriptor layerDesc;
-    layerDesc.m_CifgEnabled       = true;
-    layerDesc.m_PeepholeEnabled   = false;
-    layerDesc.m_ProjectionEnabled = false;
-    layerDesc.m_LayerNormEnabled  = true;
-
-    layerDesc.m_CellClip       = 0.0f;
-    layerDesc.m_ProjectionClip = 0.0f;
-
-    layerDesc.m_HiddenStateZeroPoint = 0;
-    layerDesc.m_HiddenStateScale     = 0.007f;
-
-    layerDesc.m_InputIntermediateScale  = 0.007059f;
-    layerDesc.m_ForgetIntermediateScale = 0.007812f;
-    layerDesc.m_CellIntermediateScale   = 0.007059f;
-    layerDesc.m_OutputIntermediateScale = 0.007812f;
-
-    QLstmLayer* const layer = graph.AddLayer<QLstmLayer>(layerDesc, "qLstm");
-
-    unsigned int numBatches = 2;
-    unsigned int inputSize  = 4;
-    unsigned int numUnits   = 4;
-    unsigned int outputSize = 4;
-
-    // Scale/Offset quantization info
-    float inputScale    = 0.0078125f;
-    int32_t inputOffset = 0;
-
-    // if (!projectionEnabled) outputScale == hiddenStateScale
-    float outputScale    = layerDesc.m_HiddenStateScale;
-    int32_t outputOffset = layerDesc.m_HiddenStateZeroPoint;
-
-    float cellStateScale    = 3.05176e-05f;
-    int32_t cellStateOffset = 0;
-
-    float weightsScale    = 0.00784314f;
-    int32_t weightsOffset = 0;
-
-    float layerNormScale    = 3.05182e-05f;
-    int32_t layerNormOffset = 0;
-
-    float biasScale    = layerNormScale / 1024;
-    int32_t biasOffset = 0;
-
-    // Weights and bias tensor and quantization info
-    armnn::TensorInfo inputWeightsInfo({outputSize, inputSize},
-                                       armnn::DataType::QSymmS8,
-                                       weightsScale,
-                                       weightsOffset);
-
-    armnn::TensorInfo recurrentWeightsInfo({outputSize, outputSize},
-                                           armnn::DataType::QSymmS8,
-                                           weightsScale,
-                                           weightsOffset);
-
-    armnn::TensorInfo biasInfo({outputSize}, armnn::DataType::Signed32, biasScale, biasOffset);
-
-    armnn::TensorInfo layerNormWeightsInfo({numUnits}, armnn::DataType::QSymmS16, layerNormScale, layerNormOffset);
-
-    // Create and allocate tensors
-    layer->m_BasicParameters.m_InputToForgetWeights = std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
-    layer->m_BasicParameters.m_InputToCellWeights = std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
-    layer->m_BasicParameters.m_InputToOutputWeights = std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
-
-    layer->m_BasicParameters.m_RecurrentToForgetWeights =
-            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
-    layer->m_BasicParameters.m_RecurrentToCellWeights =
-            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
-    layer->m_BasicParameters.m_RecurrentToOutputWeights =
-            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
-
-    layer->m_BasicParameters.m_ForgetGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
-    layer->m_BasicParameters.m_CellBias = std::make_unique<ScopedTensorHandle>(biasInfo);
-    layer->m_BasicParameters.m_OutputGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
-
-    layer->m_LayerNormParameters.m_ForgetLayerNormWeights =
-            std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
-    layer->m_LayerNormParameters.m_CellLayerNormWeights =
-            std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
-    layer->m_LayerNormParameters.m_OutputLayerNormWeights =
-            std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
-
-    layer->m_BasicParameters.m_InputToForgetWeights->Allocate();
-    layer->m_BasicParameters.m_InputToCellWeights->Allocate();
-    layer->m_BasicParameters.m_InputToOutputWeights->Allocate();
-
-    layer->m_BasicParameters.m_RecurrentToForgetWeights->Allocate();
-    layer->m_BasicParameters.m_RecurrentToCellWeights->Allocate();
-    layer->m_BasicParameters.m_RecurrentToOutputWeights->Allocate();
-
-    layer->m_BasicParameters.m_ForgetGateBias->Allocate();
-    layer->m_BasicParameters.m_CellBias->Allocate();
-    layer->m_BasicParameters.m_OutputGateBias->Allocate();
-
-    layer->m_LayerNormParameters.m_ForgetLayerNormWeights->Allocate();
-    layer->m_LayerNormParameters.m_CellLayerNormWeights->Allocate();
-    layer->m_LayerNormParameters.m_OutputLayerNormWeights->Allocate();
-
-    // Input and output layers
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const outputStateIn = graph.AddLayer<InputLayer>(1, "outputStateIn");
-    Layer* const cellStateIn = graph.AddLayer<InputLayer>(2, "cellStateIn");
-
-    Layer* const outputStateOut = graph.AddLayer<OutputLayer>(0, "outputStateOut");
-    Layer* const cellStateOut = graph.AddLayer<OutputLayer>(1, "cellStateOut");
-    Layer* const output = graph.AddLayer<OutputLayer>(2, "output");
-
-    // Input/Output tensor info
-    armnn::TensorInfo inputInfo({numBatches , inputSize},
-                                armnn::DataType::QAsymmS8,
-                                inputScale,
-                                inputOffset);
-
-    armnn::TensorInfo cellStateInfo({numBatches , numUnits},
-                                    armnn::DataType::QSymmS16,
-                                    cellStateScale,
-                                    cellStateOffset);
-
-    armnn::TensorInfo outputStateInfo({numBatches , outputSize},
-                                      armnn::DataType::QAsymmS8,
-                                      outputScale,
-                                      outputOffset);
-
-    // Connect layers to slots
-    Connect(input, layer, inputInfo, 0, 0);
-    Connect(outputStateIn, layer, outputStateInfo, 0, 1);
-    Connect(cellStateIn, layer, cellStateInfo, 0, 2);
-
-    Connect(layer, outputStateOut, outputStateInfo, 0, 0);
-    Connect(layer, cellStateOut, cellStateInfo, 1, 0);
-    Connect(layer, output, outputStateInfo, 2, 0);
-
-    CreateTensorHandles(graph, factory);
-
-    // Create and check workload
-    auto workload = MakeAndCheckWorkload<QLstmWorkload>(*layer, factory);
-    QLstmQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_CellClip == 0.0f);
-    CHECK(queueDescriptor.m_Parameters.m_ProjectionClip == 0.0f);
-    CHECK(queueDescriptor.m_Inputs.size() == 3);
-    CHECK(queueDescriptor.m_Outputs.size() == 3);
-
-    CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == inputWeightsInfo));
-    CHECK((queueDescriptor.m_InputToCellWeights->GetTensorInfo() == inputWeightsInfo));
-    CHECK((queueDescriptor.m_InputToOutputWeights->GetTensorInfo() == inputWeightsInfo));
-
-    CHECK((queueDescriptor.m_RecurrentToForgetWeights->GetTensorInfo() == recurrentWeightsInfo));
-    CHECK((queueDescriptor.m_RecurrentToCellWeights->GetTensorInfo() == recurrentWeightsInfo));
-    CHECK((queueDescriptor.m_RecurrentToOutputWeights->GetTensorInfo() == recurrentWeightsInfo));
-
-    CHECK((queueDescriptor.m_ForgetGateBias->GetTensorInfo() == biasInfo));
-    CHECK((queueDescriptor.m_CellBias->GetTensorInfo() == biasInfo));
-    CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() == biasInfo));
-
-    return workload;
-}
-
-template <typename Convolution2dWorkload, armnn::DataType DataType>
-std::unique_ptr<Convolution2dWorkload> CreateDirectConvolution2dWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                       armnn::Graph&            graph)
-{
-    // Creates the layer we're testing.
-    Convolution2dDescriptor layerDesc;
-    layerDesc.m_PadLeft = 1;
-    layerDesc.m_PadRight = 1;
-    layerDesc.m_PadTop = 1;
-    layerDesc.m_PadBottom = 1;
-    layerDesc.m_StrideX = 1;
-    layerDesc.m_StrideY = 1;
-    layerDesc.m_BiasEnabled = true;
-
-    Convolution2dLayer* const layer = graph.AddLayer<Convolution2dLayer>(layerDesc, "layer");
-
-    float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
-    float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
-
-    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo({ 2, 3, 3, 3 }, DataType, inputsQScale));
-    layer->m_Bias   = std::make_unique<ScopedTensorHandle>
-        (TensorInfo({2},  GetBiasDataType(DataType), inputsQScale));
-    layer->m_Weight->Allocate();
-    layer->m_Bias->Allocate();
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    Connect(input, layer, TensorInfo({2, 3, 6, 6}, DataType, inputsQScale));
-    Connect(layer, output, TensorInfo({2, 2, 6, 6}, DataType, outputQScale));
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory);
-
-    Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
-    CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadRight == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
-    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == true);
-
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo({2, 3, 3, 3},
-        DataType, inputsQScale)));
-    CHECK((queueDescriptor.m_Bias->GetTensorInfo()
-                == TensorInfo({2},  GetBiasDataType(DataType), inputsQScale)));
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename DepthwiseConvolution2dFloat32Workload, armnn::DataType DataType>
-std::unique_ptr<DepthwiseConvolution2dFloat32Workload> CreateDepthwiseConvolution2dWorkloadTest(
-    armnn::IWorkloadFactory& factory, armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW)
-{
-    // Creates the layer we're testing.
-    DepthwiseConvolution2dDescriptor layerDesc;
-    layerDesc.m_PadLeft     = 1;
-    layerDesc.m_PadRight    = 2;
-    layerDesc.m_PadTop      = 1;
-    layerDesc.m_PadBottom   = 2;
-    layerDesc.m_StrideX     = 1;
-    layerDesc.m_StrideY     = 1;
-    layerDesc.m_BiasEnabled = false;
-    layerDesc.m_DataLayout  = dataLayout;
-
-    DepthwiseConvolution2dLayer* const layer = graph.AddLayer<DepthwiseConvolution2dLayer>(layerDesc, "layer");
-
-    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo({1, 4, 4, 2}, DataType)); // [ 1, H, W, I*M ]
-    layer->m_Weight->Allocate();
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
-                TensorShape{ 2, 2, 5, 5 } : TensorShape{ 2, 5, 5, 2 };
-    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
-                TensorShape{ 2, 2, 5, 5 } : TensorShape{ 2, 5, 5, 2 };
-
-    // Connects up.
-    Connect(input, layer, TensorInfo(inputShape, DataType));
-    Connect(layer, output, TensorInfo(outputShape, DataType));
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<DepthwiseConvolution2dFloat32Workload>(*layer, factory);
-
-    DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
-    CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadRight == 2);
-    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 2);
-    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == false);
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo({1, 4, 4, 2}, DataType)));
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename FullyConnectedWorkload, armnn::DataType DataType>
-std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                         armnn::Graph&            graph)
-{
-    // Creates the layer we're testing.
-    FullyConnectedDescriptor layerDesc;
-    layerDesc.m_BiasEnabled = false;
-    layerDesc.m_TransposeWeightMatrix = true;
-
-    FullyConnectedLayer* const layer = graph.AddLayer<FullyConnectedLayer>(layerDesc, "layer");
-
-    float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
-    float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
-
-    // As optimization isn't run member variables need to be updated.
-    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo({7, 20}, DataType, inputsQScale, 0));
-    layer->m_Weight->Allocate();
-
-    armnn::TensorInfo weightsTensorInfo({7, 20}, DataType, inputsQScale);
-    weightsTensorInfo.SetConstant();
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    auto const weights = graph.AddLayer<ConstantLayer>("weights");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    weights->m_LayerOutput = std::make_unique<ScopedTensorHandle>(weightsTensorInfo);
-    weights->m_LayerOutput->Allocate();
-
-    // Connects up.
-    Connect(input, layer, TensorInfo({3, 1, 4, 5}, DataType, inputsQScale), 0, 0);
-    Connect(weights, layer, weightsTensorInfo, 0, 1);
-    Connect(layer, output, TensorInfo({3, 7}, DataType, outputQScale));
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
-
-    FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix == true);
-
-    CHECK(queueDescriptor.m_Inputs.size() == 2);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename FullyConnectedWorkload, armnn::DataType DataType>
-std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWithBlobWorkloadTest
-    (armnn::IWorkloadFactory& factory,
-     armnn::Graph& graph)
-{
-    // Creates the layer we're testing.
-    FullyConnectedDescriptor layerDesc;
-    layerDesc.m_BiasEnabled = true;
-    layerDesc.m_TransposeWeightMatrix = true;
-
-    FullyConnectedLayer* const layer = graph.AddLayer<FullyConnectedLayer>(layerDesc, "layer");
-
-    float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
-    float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
-
-    // As optimization isn't run member variables need to be updated.
-    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo({7, 20}, DataType, inputsQScale, 0));
-    layer->m_Bias   = std::make_unique<ScopedTensorHandle>(TensorInfo({7}, GetBiasDataType(DataType), inputsQScale));
-    layer->m_Weight->Allocate();
-    layer->m_Bias->Allocate();
-
-    armnn::TensorInfo weightsTensorInfo({7, 20}, DataType, inputsQScale);
-    armnn::TensorInfo biasesTensorInfo({7}, GetBiasDataType(DataType), inputsQScale);
-    weightsTensorInfo.SetConstant();
-    biasesTensorInfo.SetConstant();
-
-    auto activationDesc = std::make_shared<ActivationDescriptor>();
-    activationDesc->m_A        = 10.0f;
-    activationDesc->m_B        = 5.0f;
-    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
-
-    layer->SetAdditionalInfoForObject(activationDesc);
-
-    // Check that the additional information can be queried from the layer
-    std::shared_ptr<ActivationDescriptor> activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(static_cast<ActivationFunction>(activationDescPtr->m_Function) ==
-        armnn::ActivationFunction::BoundedReLu);
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    auto const weights = graph.AddLayer<ConstantLayer>("weights");
-    auto const biases = graph.AddLayer<ConstantLayer>("biases");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    weights->m_LayerOutput = std::make_unique<ScopedTensorHandle>(weightsTensorInfo);
-    weights->m_LayerOutput->Allocate();
-    biases->m_LayerOutput = std::make_unique<ScopedTensorHandle>(biasesTensorInfo);
-    biases->m_LayerOutput->Allocate();
-
-    // Connects up.
-    Connect(input, layer, TensorInfo({3, 1, 4, 5}, DataType, inputsQScale), 0, 0);
-    Connect(weights, layer, weightsTensorInfo, 0, 1);
-    Connect(biases, layer, biasesTensorInfo, 0, 2);
-    Connect(layer, output, TensorInfo({3, 7}, DataType, outputQScale));
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
-
-    FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
-
-    const ActivationDescriptor* queueDescBlobPtr = queueDescriptor.GetAdditionalInformation<ActivationDescriptor>();
-    IgnoreUnused(queueDescBlobPtr);
-
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
-    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
-    ARMNN_ASSERT(
-        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
-    );
-
-    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == true);
-    CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix == true);
-    CHECK(queueDescriptor.m_Inputs.size() == 3);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename FullyConnectedWorkload, armnn::DataType DataType>
-std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWorkloadWeightsBiasesAsInputsTest
-    (armnn::IWorkloadFactory& factory,
-     armnn::Graph&            graph)
-{
-    // Creates the layer we're testing.
-    FullyConnectedDescriptor layerDesc;
-    layerDesc.m_BiasEnabled = true;
-    layerDesc.m_TransposeWeightMatrix = true;
-    layerDesc.m_ConstantWeights = false;
-
-    FullyConnectedLayer* const layer = graph.AddLayer<FullyConnectedLayer>(layerDesc, "layer");
-
-    float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
-    float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
-
-    // Creates extra layers with weights and biases as input layers.
-    Layer* const input   = graph.AddLayer<InputLayer>(1, "input");
-    Layer* const weights = graph.AddLayer<InputLayer>(2, "weights");
-    Layer* const biases  = graph.AddLayer<InputLayer>(3, "biases");
-    Layer* const output  = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    Connect(input, layer, TensorInfo({3, 1, 4, 5}, DataType, inputsQScale), 0, 0);
-    Connect(weights, layer, TensorInfo({7, 20}, DataType, inputsQScale), 0, 1);
-    Connect(biases, layer, TensorInfo({7}, GetBiasDataType(DataType), inputsQScale), 0, 2);
-    Connect(layer, output, TensorInfo({3, 7}, DataType, outputQScale));
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
-
-    FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
-
-    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == true);
-    CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix == true);
-    CHECK(queueDescriptor.m_Parameters.m_ConstantWeights == false);
-    CHECK(queueDescriptor.m_Inputs.size() == 3);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-
-template <typename NormalizationWorkload, armnn::DataType DataType>
-std::unique_ptr<NormalizationWorkload> CreateNormalizationWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                       armnn::Graph& graph,
-                                                                       DataLayout dataLayout = DataLayout::NCHW)
-{
-    // Creates the layer we're testing.
-    NormalizationDescriptor layerDesc;
-    layerDesc.m_NormChannelType = NormalizationAlgorithmChannel::Across;
-    layerDesc.m_NormMethodType = NormalizationAlgorithmMethod::LocalBrightness;
-    layerDesc.m_NormSize = 3;
-    layerDesc.m_Alpha = 0.5f;
-    layerDesc.m_Beta = -1.0f;
-    layerDesc.m_K = 0.2f;
-    layerDesc.m_DataLayout = dataLayout;
-
-    NormalizationLayer* layer = graph.AddLayer<NormalizationLayer>(layerDesc, "layer");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
-                TensorShape{ 3, 5, 5, 1 } : TensorShape{ 3, 1, 5, 5 };
-    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
-                TensorShape{ 3, 5, 5, 1 } : TensorShape{ 3, 1, 5, 5 };
-
-    // Connects up.
-    armnn::TensorInfo inputTensorInfo(inputShape, DataType);
-    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
-    Connect(input, layer, inputTensorInfo);
-    Connect(layer, output, outputTensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<NormalizationWorkload>(*layer, factory);
-
-    NormalizationQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK((queueDescriptor.m_Parameters.m_NormChannelType == NormalizationAlgorithmChannel::Across));
-    CHECK((queueDescriptor.m_Parameters.m_NormMethodType == NormalizationAlgorithmMethod::LocalBrightness));
-    CHECK(queueDescriptor.m_Parameters.m_NormSize == 3);
-    CHECK(queueDescriptor.m_Parameters.m_Alpha == 0.5f);
-    CHECK(queueDescriptor.m_Parameters.m_Beta == -1.0f);
-    CHECK(queueDescriptor.m_Parameters.m_K == 0.2f);
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename Pooling2dWorkload, armnn::DataType DataType>
-std::unique_ptr<Pooling2dWorkload> CreatePooling2dWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                               armnn::Graph&            graph,
-                                                               DataLayout dataLayout = DataLayout::NCHW)
-{
-    // Creates the layer we're testing.
-    Pooling2dDescriptor layerDesc;
-    layerDesc.m_PoolType = PoolingAlgorithm::Average;
-    layerDesc.m_PoolWidth = 3;
-    layerDesc.m_PoolHeight = 3;
-    layerDesc.m_PadLeft = 2;
-    layerDesc.m_PadRight = 2;
-    layerDesc.m_PadTop = 1;
-    layerDesc.m_PadBottom = 1;
-    layerDesc.m_StrideX = 2;
-    layerDesc.m_StrideY = 3;
-    layerDesc.m_OutputShapeRounding = OutputShapeRounding::Floor;
-    layerDesc.m_DataLayout = dataLayout;
-
-    Pooling2dLayer* const layer = graph.AddLayer<Pooling2dLayer>(layerDesc, "layer");
-
-    // Create extra layers
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
-    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
-
-    // Connect up
-    Connect(input, layer, TensorInfo(inputShape, DataType));
-    Connect(layer, output, TensorInfo(outputShape, DataType));
-    CreateTensorHandles(graph, factory);
-
-    // Make the workload and checks it
-    auto workload = MakeAndCheckWorkload<Pooling2dWorkload>(*layer, factory);
-
-    Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK((queueDescriptor.m_Parameters.m_PoolType == PoolingAlgorithm::Average));
-    CHECK((queueDescriptor.m_Parameters.m_OutputShapeRounding == OutputShapeRounding::Floor));
-    CHECK(queueDescriptor.m_Parameters.m_PoolWidth == 3);
-    CHECK(queueDescriptor.m_Parameters.m_PoolHeight == 3);
-    CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
-    CHECK(queueDescriptor.m_Parameters.m_StrideY == 3);
-    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 2);
-    CHECK(queueDescriptor.m_Parameters.m_PadRight == 2);
-    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
-    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Return so we can do extra, backend-specific tests
-    return workload;
-}
-
-template <typename SoftmaxWorkload, armnn::DataType DataType>
-std::unique_ptr<SoftmaxWorkload> CreateSoftmaxWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                           armnn::Graph&            graph)
-{
-    // Create the layer we're testing.
-    SoftmaxDescriptor softmaxDescriptor;
-    // Set Axis to -1 if CL or Neon until further Axes are supported.
-    if (factory.GetBackendId() == armnn::Compute::CpuAcc || factory.GetBackendId() == armnn::Compute::GpuAcc)
-    {
-        softmaxDescriptor.m_Axis = -1;
-    }
-
-    Layer* const layer = graph.AddLayer<SoftmaxLayer>(softmaxDescriptor, "layer");
-    // Create extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connect up
-    armnn::TensorInfo tensorInfo({4, 1}, DataType);
-    if (DataType == armnn::DataType::QAsymmU8)
-    {
-        tensorInfo.SetQuantizationOffset(0);
-        tensorInfo.SetQuantizationScale(1.f / 256);
-    }
-    else if (DataType == armnn::DataType::QAsymmS8)
-    {
-        tensorInfo.SetQuantizationOffset(-128);
-        tensorInfo.SetQuantizationScale(1.f / 256);
-    }
-
-    Connect(input, layer, tensorInfo);
-    Connect(layer, output, tensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Make the workload and checks it.
-    auto workload = MakeAndCheckWorkload<SoftmaxWorkload>(*layer, factory);
-
-    SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Return so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template<typename SplitterWorkload, armnn::DataType DataType>
-std::unique_ptr<SplitterWorkload>
-    CreateSplitterWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph)
-{
-    // Create the layer we're testing.
-    // NOTE: need three dimensions channels, height/y, width/x because the Compute
-    //       library restricts subtensors to have the same x and y dimensions as
-    //       their parent tensors, and therefore the origin on the x and y dimension
-    //       has to be zero for any view. So we need a third dimension to split...
-    // NOTE: arguments are: number of views, number of dimensions.
-    ViewsDescriptor layerDesc(3, 3);
-    // NOTE: arguments are: view, dimension, value.
-    layerDesc.SetViewOriginCoord(0, 0, 0);
-    layerDesc.SetViewOriginCoord(1, 0, 1);
-    layerDesc.SetViewOriginCoord(2, 0, 3);
-
-    Layer* const layer = graph.AddLayer<SplitterLayer>(layerDesc, "layer");
-
-    // Adds extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output0 = graph.AddLayer<OutputLayer>(0, "output0");
-    Layer* const output1 = graph.AddLayer<OutputLayer>(1, "output1");
-    Layer* const output2 = graph.AddLayer<OutputLayer>(2, "output2");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo({5, 7, 7}, DataType);
-    Connect(input, layer, tensorInfo);
-
-    armnn::TensorInfo output0Info({1, 7, 7}, DataType);
-    armnn::TensorInfo output1Info({2, 7, 7}, DataType);
-    armnn::TensorInfo output2Info({2, 7, 7}, DataType);
-
-    Connect(layer, output0, output0Info, 0, 0);
-    Connect(layer, output1, output1Info, 1, 0);
-    Connect(layer, output2, output2Info, 2, 0);
-
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<SplitterWorkload>(*layer, factory);
-
-    SplitterQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 3);
-    CHECK(queueDescriptor.m_ViewOrigins.size() == 3);
-
-    CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[0] == 0);
-    CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[0] == 1);
-    CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[0] == 3);
-    CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[1] == 0);
-    CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[1] == 0);
-    CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[1] == 0);
-    CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[2] == 0);
-    CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[2] == 0);
-    CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[2] == 0);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-/// This function constructs a graph with both a splitter and a concat, and returns a pair of the workloads.
-template<typename SplitterWorkload, typename ConcatWorkload, armnn::DataType DataType>
-std::pair<std::unique_ptr<SplitterWorkload>, std::unique_ptr<ConcatWorkload>>
-    CreateSplitterConcatWorkloadTest(armnn::IWorkloadFactory &factory, armnn::Graph &graph)
-{
-    armnn::TensorInfo inputTensorInfo({ 1, 2, 100, 10 }, DataType);
-
-    armnn::TensorInfo splitTensorInfo1({ 1, 1, 100, 10 }, DataType);
-    armnn::TensorInfo splitTensorInfo2({ 1, 1, 100, 10 }, DataType);
-
-    //Constructs the graph.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-
-    armnn::ViewsDescriptor splitterViews(2);
-    splitterViews.SetViewOriginCoord(0, 0, 0);
-    splitterViews.SetViewOriginCoord(0, 1, 0);
-    splitterViews.SetViewOriginCoord(0, 2, 0);
-    splitterViews.SetViewOriginCoord(0, 3, 0);
-
-    splitterViews.SetViewOriginCoord(1, 0, 0);
-    splitterViews.SetViewOriginCoord(1, 1, 1);
-    splitterViews.SetViewOriginCoord(1, 2, 0);
-    splitterViews.SetViewOriginCoord(1, 3, 0);
-
-    // create splitter layer
-    Layer* const splitter = graph.AddLayer<SplitterLayer>(splitterViews, "splitter");
-    CHECK(splitter);
-
-    armnn::OriginsDescriptor concatViews(2);
-    concatViews.SetViewOriginCoord(0, 0, 0);
-    concatViews.SetViewOriginCoord(0, 1, 1);
-    concatViews.SetViewOriginCoord(0, 2, 0);
-    concatViews.SetViewOriginCoord(0, 3, 0);
-
-    concatViews.SetViewOriginCoord(1, 0, 0);
-    concatViews.SetViewOriginCoord(1, 1, 0);
-    concatViews.SetViewOriginCoord(1, 2, 0);
-    concatViews.SetViewOriginCoord(1, 3, 0);
-
-    // create concat layer
-    Layer* const concat = graph.AddLayer<ConcatLayer>(concatViews, "concat");
-    CHECK(concat);
-
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Adds connections.
-    // connect input to splitter
-    Connect(input, splitter, inputTensorInfo, 0, 0);
-    // connect splitter[0] to concat[1]
-    Connect(splitter, concat, splitTensorInfo1, 0, 1); // The splitter & concat are connected up.
-    // connect splitter[1] to concat[0]
-    Connect(splitter, concat, splitTensorInfo2, 1, 0); // So that the outputs are flipped round.
-    // connect concat to output
-    Connect(concat, output, inputTensorInfo, 0, 0);
-
-    // created tensor handles
-    CreateTensorHandles(graph, factory);
-
-    // created splitter workload
-    auto workloadSplitter = MakeAndCheckWorkload<SplitterWorkload>(*splitter, factory);
-    CHECK(workloadSplitter);
-    // created concat workload
-    auto workloadConcat = MakeAndCheckWorkload<ConcatWorkload>(*concat, factory);
-    CHECK(workloadConcat);
-
-    return {std::move(workloadSplitter), std::move(workloadConcat)};
-}
-
-
-/// This function constructs a graph with a splitter with two outputs. Each of the outputs is then
-/// connected to two different activation layers
-template<typename SplitterWorkload, typename ActivationWorkload, armnn::DataType DataType>
-void CreateSplitterMultipleInputsOneOutputWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph,
-                                 std::unique_ptr<SplitterWorkload>& wlSplitter,
-                                 std::unique_ptr<ActivationWorkload>& wlActiv0_0,
-                                 std::unique_ptr<ActivationWorkload>& wlActiv0_1,
-                                 std::unique_ptr<ActivationWorkload>& wlActiv1_0,
-                                 std::unique_ptr<ActivationWorkload>& wlActiv1_1)
-{
-    armnn::TensorInfo inputTensorInfo ({ 1, 3, 100, 50 }, DataType);
-    armnn::TensorInfo splitTensorInfo1({ 1, 1, 100, 50 }, DataType);
-    armnn::TensorInfo splitTensorInfo2({ 1, 2, 100, 50 }, DataType);
-
-    //Constructs the graph.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-
-    armnn::ViewsDescriptor splitterViews(2);
-
-    splitterViews.SetViewOriginCoord(0, 0, 0);
-    splitterViews.SetViewOriginCoord(0, 1, 0);
-    splitterViews.SetViewOriginCoord(0, 2, 0);
-    splitterViews.SetViewOriginCoord(0, 3, 0);
-
-    splitterViews.SetViewOriginCoord(1, 0, 0);
-    splitterViews.SetViewOriginCoord(1, 1, 1);
-    splitterViews.SetViewOriginCoord(1, 2, 0);
-    splitterViews.SetViewOriginCoord(1, 3, 0);
-
-    Layer* const splitter = graph.AddLayer<SplitterLayer>(splitterViews, "splitter");
-
-    armnn::ActivationDescriptor activationDesc;
-
-    Layer* const activ0_0 = graph.AddLayer<ActivationLayer>(activationDesc, "activ0_0");
-    Layer* const activ0_1 = graph.AddLayer<ActivationLayer>(activationDesc, "activ0_1");
-    Layer* const activ1_0 = graph.AddLayer<ActivationLayer>(activationDesc, "activ1_0");
-    Layer* const activ1_1 = graph.AddLayer<ActivationLayer>(activationDesc, "activ1_1");
-
-    Layer* const output1 = graph.AddLayer<OutputLayer>(1, "output1");
-    Layer* const output2 = graph.AddLayer<OutputLayer>(2, "output2");
-    Layer* const output3 = graph.AddLayer<OutputLayer>(3, "output3");
-    Layer* const output4 = graph.AddLayer<OutputLayer>(4, "output4");
-
-    // Adds connections.
-    Connect(input, splitter, inputTensorInfo, 0, 0);
-    Connect(splitter, activ0_0, splitTensorInfo1, 0, 0);
-    Connect(splitter, activ0_1, splitTensorInfo1, 0, 0);
-
-    Connect(splitter, activ1_0, splitTensorInfo2, 1, 0);
-    Connect(splitter, activ1_1, splitTensorInfo2, 1, 0);
-
-    Connect(activ0_0, output1, splitTensorInfo1, 0, 0);
-    Connect(activ0_1, output2, splitTensorInfo1, 0, 0);
-    Connect(activ1_0, output3, splitTensorInfo2, 0, 0);
-    Connect(activ1_1, output4, splitTensorInfo2, 0, 0);
-
-    CreateTensorHandles(graph, factory);
-
-    auto workloadSplitter = MakeAndCheckWorkload<SplitterWorkload>(*splitter, factory);
-    auto workloadActiv0_0 = MakeAndCheckWorkload<ActivationWorkload>(*activ0_0, factory);
-    auto workloadActiv0_1 = MakeAndCheckWorkload<ActivationWorkload>(*activ0_1, factory);
-    auto workloadActiv1_0 = MakeAndCheckWorkload<ActivationWorkload>(*activ1_0, factory);
-    auto workloadActiv1_1 = MakeAndCheckWorkload<ActivationWorkload>(*activ1_1, factory);
-
-    wlSplitter = std::move(workloadSplitter);
-    wlActiv0_0 = std::move(workloadActiv0_0);
-    wlActiv0_1 = std::move(workloadActiv0_1);
-    wlActiv1_0 = std::move(workloadActiv1_0);
-    wlActiv1_1 = std::move(workloadActiv1_1);
-}
-
-template <typename ResizeWorkload, armnn::DataType DataType>
-std::unique_ptr<ResizeWorkload> CreateResizeBilinearWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                 armnn::Graph& graph,
-                                                                 DataLayout dataLayout = DataLayout::NCHW)
-{
-    TensorShape inputShape;
-    TensorShape outputShape;
-
-    switch (dataLayout) {
-        case DataLayout::NHWC:
-            inputShape =  { 2, 4, 4, 3 };
-            outputShape = { 2, 2, 2, 3 };
-            break;
-        case DataLayout::NCHW:
-        default:
-            inputShape =  { 2, 3, 4, 4 };
-            outputShape = { 2, 3, 2, 2 };
-    }
-
-    // Creates the layer we're testing.
-    ResizeDescriptor resizeDesc;
-    armnnUtils::DataLayoutIndexed dimensionIndices = dataLayout;
-    resizeDesc.m_Method       = ResizeMethod::Bilinear;
-    resizeDesc.m_TargetWidth  = outputShape[dimensionIndices.GetWidthIndex()];
-    resizeDesc.m_TargetHeight = outputShape[dimensionIndices.GetHeightIndex()];
-    resizeDesc.m_DataLayout   = dataLayout;
-    Layer* const layer = graph.AddLayer<ResizeLayer>(resizeDesc, "resize");
-
-    // Creates extra layers.
-    Layer* const input  = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo inputTensorInfo(inputShape, DataType);
-    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
-    Connect(input, layer, inputTensorInfo);
-    Connect(layer, output, outputTensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<ResizeWorkload>(*layer, factory);
-
-    auto queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size()  == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-    CHECK(queueDescriptor.m_Parameters.m_DataLayout == dataLayout);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename BatchToSpaceNdWorkload, armnn::DataType DataType>
-std::unique_ptr<BatchToSpaceNdWorkload> CreateBatchToSpaceNdWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                         armnn::Graph&  graph)
-{
-    BatchToSpaceNdDescriptor desc;
-    Layer* const layer = graph.AddLayer<BatchToSpaceNdLayer>(desc, "batchToSpace");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo tensorInfo({1, 1, 1, 1}, DataType);
-
-    Connect(input, layer, tensorInfo);
-    Connect(layer, output, tensorInfo);
-
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<BatchToSpaceNdWorkload>(*layer, factory);
-
-    BatchToSpaceNdQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    return workload;
-}
-
-template <typename LogSoftmaxWorkload, armnn::DataType DataType>
-std::unique_ptr<LogSoftmaxWorkload> CreateLogSoftmaxWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                 armnn::Graph& graph)
-{
-    // Create the layer we're testing.
-    LogSoftmaxDescriptor logSoftmaxDescriptor;
-    // Set Axis to -1 if CL or Neon until further Axes are supported.
-    if (factory.GetBackendId() == armnn::Compute::CpuAcc || factory.GetBackendId() == armnn::Compute::GpuAcc)
-    {
-        logSoftmaxDescriptor.m_Axis = -1;
-    }
-
-    Layer* const layer = graph.AddLayer<LogSoftmaxLayer>(logSoftmaxDescriptor, "layer");
-    // Create extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connect up
-    armnn::TensorInfo tensorInfo({4, 1}, DataType);
-
-    Connect(input, layer, tensorInfo);
-    Connect(layer, output, tensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Make the workload and checks it.
-    auto workload = MakeAndCheckWorkload<LogSoftmaxWorkload>(*layer, factory);
-
-    LogSoftmaxQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Return so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename L2NormalizationWorkload, armnn::DataType DataType>
-std::unique_ptr<L2NormalizationWorkload> CreateL2NormalizationWorkloadTest(armnn::IWorkloadFactory& factory,
-    armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW)
-{
-    // Creates the layer we're testing.
-    L2NormalizationDescriptor layerDesc;
-    layerDesc.m_DataLayout = dataLayout;
-
-    Layer* const layer = graph.AddLayer<L2NormalizationLayer>(layerDesc, "l2norm");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
-                TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
-    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
-                TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
-
-    // Connects up.
-    armnn::TensorInfo inputTensorInfo(inputShape, DataType);
-    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
-    Connect(input, layer, inputTensorInfo);
-    Connect(layer, output, outputTensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<L2NormalizationWorkload>(*layer, factory);
-
-    L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename ReshapeWorkload, armnn::DataType DataType>
-std::unique_ptr<ReshapeWorkload> CreateReshapeWorkloadTest(armnn::IWorkloadFactory& factory,
-    armnn::Graph& graph)
-{
-    // Creates the layer we're testing.
-    TensorShape outputShape({ 1, 4 });
-    ReshapeDescriptor reshapeDesc;
-    reshapeDesc.m_TargetShape = outputShape;
-    Layer* const layer = graph.AddLayer<ReshapeLayer>(reshapeDesc, "layer");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo inputTensorInfo({ 4, 1 }, DataType);
-    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
-    Connect(input, layer, inputTensorInfo);
-    Connect(layer, output, outputTensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<ReshapeWorkload>(*layer, factory);
-
-    ReshapeQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename ConvertFp16ToFp32Float32Workload>
-std::unique_ptr<ConvertFp16ToFp32Float32Workload> CreateConvertFp16ToFp32WorkloadTest(
-    armnn::IWorkloadFactory& factory, armnn::Graph& graph)
-{
-    // Creates the layer we're testing.
-    ConvertFp16ToFp32Layer* const layer = graph.AddLayer<ConvertFp16ToFp32Layer>("Fp16ToFp32Converter");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo inputTensorInfo({1, 3, 2, 3}, armnn::DataType::Float16);
-    armnn::TensorInfo outputTensorInfo({1, 3, 2, 3}, armnn::DataType::Float32);
-    Connect(input, layer, inputTensorInfo);
-    Connect(layer, output, outputTensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<ConvertFp16ToFp32Float32Workload>(*layer, factory);
-
-    ConvertFp16ToFp32QueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename ConvertFp32ToFp16Float16Workload>
-std::unique_ptr<ConvertFp32ToFp16Float16Workload> CreateConvertFp32ToFp16WorkloadTest(
-    armnn::IWorkloadFactory& factory, armnn::Graph& graph)
-{
-    // Creates the layer we're testing.
-    ConvertFp32ToFp16Layer* const layer = graph.AddLayer<ConvertFp32ToFp16Layer>("Fp32ToFp16Converter");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo inputTensorInfo({1, 3, 2, 3}, armnn::DataType::Float32);
-    armnn::TensorInfo outputTensorInfo({1, 3, 2, 3}, armnn::DataType::Float16);
-    Connect(input, layer, inputTensorInfo);
-    Connect(layer, output, outputTensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<ConvertFp32ToFp16Float16Workload>(*layer, factory);
-
-    ConvertFp32ToFp16QueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename MeanWorkload, armnn::DataType DataType>
-std::unique_ptr<MeanWorkload> CreateMeanWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph)
-{
-    // Reduce along the first and second dimensions, and do not keep the reduced dimensions.
-    MeanDescriptor descriptor({ 1, 2 }, false);
-
-    // Creates the layer we're testing.
-    Layer* const layer = graph.AddLayer<MeanLayer>(descriptor, "mean");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo inputTensorInfo({ 1, 3, 7, 4 }, DataType);
-    armnn::TensorInfo outputTensorInfo({ 1, 4 }, DataType);
-    Connect(input, layer, inputTensorInfo);
-    Connect(layer, output, outputTensorInfo);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<MeanWorkload>(*layer, factory);
-
-    MeanQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Parameters.m_Axis == descriptor.m_Axis);
-    CHECK(queueDescriptor.m_Parameters.m_KeepDims == descriptor.m_KeepDims);
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template<typename ConcatWorkload, armnn::DataType DataType>
-std::unique_ptr<ConcatWorkload> CreateConcatWorkloadTest(armnn::IWorkloadFactory &factory,
-                                                         armnn::Graph &graph,
-                                                         const armnn::TensorShape &outputShape,
-                                                         unsigned int concatAxis)
-{
-    armnn::TensorInfo inputTensorInfo({ 2, 3, 2, 5 }, DataType);
-    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
-
-    // Constructs the graph.
-    Layer* const input0 = graph.AddLayer<InputLayer>(0, "input0");
-    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
-    armnn::OriginsDescriptor descriptor;
-
-    std::vector<armnn::TensorShape> inputShapes{{ 2, 3, 2, 5 }, { 2, 3, 2, 5 }};
-
-    descriptor = CreateDescriptorForConcatenation(inputShapes.begin(),
-                                                  inputShapes.end(),
-                                                  concatAxis);
-
-    // create concat layer
-    Layer* const concat = graph.AddLayer<ConcatLayer>(descriptor, "concat");
-    CHECK(concat);
-
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Adds connections.
-    // connect input0 to concat
-    Connect(input0, concat, inputTensorInfo, 0, 0);
-    // connect input1 to concat
-    Connect(input1, concat, inputTensorInfo, 0, 1);
-    // connect concat to output
-    Connect(concat, output, outputTensorInfo, 0, 0);
-
-    // create tensor handles
-    CreateTensorHandles(graph, factory);
-
-    // create concat workload
-    auto workloadConcat = MakeAndCheckWorkload<ConcatWorkload>(*concat, factory);
-    CHECK(workloadConcat);
-
-    return workloadConcat;
-}
-
-template <typename PreCompiledWorkload, armnn::DataType dataType>
-std::pair<armnn::IOptimizedNetworkPtr, std::unique_ptr<PreCompiledWorkload>> CreatePreCompiledWorkloadTest(
-    armnn::IWorkloadFactory& factory,
-    armnn::Graph& graph,
-    bool biasEnabled = false)
-{
-    IgnoreUnused(graph);
-
-    // build up the structure of the network
-    armnn::INetworkPtr net(armnn::INetwork::Create());
-
-    // Add an input layer
-    armnn::IConnectableLayer* const inputLayer = net->AddInputLayer(0, "input layer");
-    CHECK(inputLayer);
-
-    // ArmNN weights tensor shape is OIHW (out channels, in channels, height, width) for NCHW
-    // ArmNN weights tensor shape is OHWI (out channels, height, width, in channels) for NHWC
-    // this test is using NHWC, so the weights shape is OHWI
-    TensorInfo weightsTensorInfo(TensorShape({16, 1, 1, 16}), dataType, 0.9f, 0, true);
-    unsigned int weightsLength = weightsTensorInfo.GetNumElements();
-
-    using WeightType = armnn::ResolveType<dataType>;
-    std::vector<WeightType> convWeightsData(weightsLength);
-    for (unsigned int i = 0; i < weightsLength; ++i)
-    {
-        convWeightsData[i] = static_cast<WeightType>(i);
-    }
-
-    armnn::ConstTensor weights(weightsTensorInfo, convWeightsData);
-
-    // Add a layer that can be used in the PreCompiled layer
-    armnn::Convolution2dDescriptor convDesc2d;
-    convDesc2d.m_StrideX = 1;
-    convDesc2d.m_StrideY = 1;
-    convDesc2d.m_BiasEnabled = biasEnabled;
-    convDesc2d.m_DataLayout = armnn::DataLayout::NHWC;
-
-    armnn::IConnectableLayer* convLayer = nullptr;
-    const std::string convLayerName("conv layer");
-
-    if (biasEnabled)
-    {
-        constexpr armnn::DataType biasDataType = ( dataType == armnn::DataType::QAsymmU8) ?
-            armnn::DataType::Signed32 : armnn::DataType::Float32;
-
-        TensorInfo biasTensorInfo(TensorShape({16}), biasDataType, 0.9f * 0.9f, 0, true);
-        unsigned int biasLength = biasTensorInfo.GetNumElements();
-
-        using BiasType = armnn::ResolveType<biasDataType>;
-        std::vector<BiasType> biasData(biasLength);
-        std::fill(biasData.begin(), biasData.end(), static_cast<BiasType>(0));
-
-        armnn::ConstTensor biases(biasTensorInfo, biasData);
-
-        // Create convolution layer with biases
-        convLayer = net->AddConvolution2dLayer(convDesc2d,
-                                              weights,
-                                              Optional<ConstTensor>(biases),
-                                              convLayerName.c_str());
-    }
-    else
-    {
-        // Create convolution layer without biases
-        convLayer = net->AddConvolution2dLayer(convDesc2d,
-                                              weights,
-                                              EmptyOptional(),
-                                              convLayerName.c_str());
-    }
-
-    CHECK(convLayer);
-
-    // Add an output layer
-    armnn::IConnectableLayer* const outputLayer = net->AddOutputLayer(0, "output layer");
-    CHECK(outputLayer);
-
-    // set the tensors in the network (NHWC format)
-    TensorInfo inputTensorInfo(TensorShape({ 1, 16, 16, 16 }), dataType);
-    if (dataType == armnn::DataType::QAsymmU8)
-    {
-        inputTensorInfo.SetQuantizationOffset(0);
-        inputTensorInfo.SetQuantizationScale(0.9f);
-    }
-
-    TensorInfo outputTensorInfo(TensorShape({1, 16, 16, 16}), dataType);
-    if (dataType == armnn::DataType::QAsymmU8)
-    {
-        outputTensorInfo.SetQuantizationOffset(0);
-        outputTensorInfo.SetQuantizationScale(0.9f);
-    }
-
-    // Connect the layers
-    inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
-    inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
-
-    convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
-    convLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
-
-    // Optimize the network for the backend supported by the factory
-    std::vector<armnn::BackendId> backends = {factory.GetBackendId()};
-    armnn::IRuntime::CreationOptions options;
-    armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
-    armnn::OptimizerOptions optimizerOptions;
-    armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec(),
-                                                               optimizerOptions);
-    CHECK(optimizedNet != nullptr);
-
-    // Find the PreCompiled layer in the optimised graph
-    armnn::Graph& optimisedGraph = GetGraphForTesting(optimizedNet.get());
-    Layer* preCompiledLayer = nullptr;
-    for (auto& layer : optimisedGraph)
-    {
-        if (layer->GetType() == LayerType::PreCompiled)
-        {
-            preCompiledLayer = layer;
-        }
-    }
-    CHECK(preCompiledLayer != nullptr);
-
-    // Create the TensorHandles.
-    CreateTensorHandles(optimisedGraph, factory);
-
-    // Make the workload and check it.
-    auto workload = MakeAndCheckWorkload<PreCompiledWorkload>(*preCompiledLayer, factory);
-
-    PreCompiledQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size()  == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns the workload so we can do extra, backend-specific tests.
-    // NOTE: We need to return the optimised network as well, otherwise it gets
-    // out of scope and the tensor handles get destructed
-    return std::make_pair(std::move(optimizedNet), std::move(workload));
-}
-
-template<typename ConstantWorkload, armnn::DataType DataType>
-std::unique_ptr<ConstantWorkload> CreateConstantWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                             armnn::Graph& graph,
-                                                             const armnn::TensorShape& outputShape)
-{
-    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
-
-    // create constant layer
-    auto constant = graph.AddLayer<ConstantLayer>("constant");
-    CHECK(constant);
-    constant->m_LayerOutput = std::make_unique<ScopedTensorHandle>(outputTensorInfo);
-
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Adds connections.
-    // connect constant to output
-    Connect(constant, output, outputTensorInfo, 0, 0);
-
-    // create tensor handles
-    CreateTensorHandles(graph, factory);
-
-    // create Constant workload"
-    auto workloadConstant = MakeAndCheckWorkload<ConstantWorkload>(*constant, factory);
-    CHECK(workloadConstant);
-
-    return workloadConstant;
-}
-
-template <typename PreluWorkload>
-std::unique_ptr<PreluWorkload> CreatePreluWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                       armnn::Graph& graph,
-                                                       const armnn::TensorShape& inputShape,
-                                                       const armnn::TensorShape& alphaShape,
-                                                       const armnn::TensorShape& outputShape,
-                                                       armnn::DataType dataType)
-{
-    // Creates the PReLU layer
-    Layer* const layer = graph.AddLayer<PreluLayer>("prelu");
-    CHECK(layer != nullptr);
-
-    // Creates extra layers
-    Layer* const input  = graph.AddLayer<InputLayer> (0, "input");
-    Layer* const alpha  = graph.AddLayer<InputLayer> (1, "alpha");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-    CHECK(input  != nullptr);
-    CHECK(alpha  != nullptr);
-    CHECK(output != nullptr);
-
-    // Connects up
-    armnn::TensorInfo inputTensorInfo (inputShape,  dataType);
-    armnn::TensorInfo alphaTensorInfo (alphaShape,  dataType);
-    armnn::TensorInfo outputTensorInfo(outputShape, dataType);
-    Connect(input, layer,  inputTensorInfo,  0, 0);
-    Connect(alpha, layer,  alphaTensorInfo,  0, 1);
-    Connect(layer, output, outputTensorInfo, 0, 0);
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it
-    auto workload = MakeAndCheckWorkload<PreluWorkload>(*layer, factory);
-
-    PreluQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 2);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    // Returns so we can do extra, backend-specific tests.
-    return workload;
-}
-
-template <typename SpaceToDepthWorkload, armnn::DataType DataType>
-std::unique_ptr<SpaceToDepthWorkload> CreateSpaceToDepthWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                                     armnn::Graph&  graph)
-{
-    SpaceToDepthDescriptor desc;
-    desc.m_BlockSize = 2;
-    Layer* const layer = graph.AddLayer<SpaceToDepthLayer>(desc, "spaceToDepth");
-
-    // Creates extra layers.
-    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-
-    // Connects up.
-    armnn::TensorInfo inputTensorInfo({ 1, 2, 2, 1 }, DataType);
-    armnn::TensorInfo outputTensorInfo({ 1, 1, 1, 4 }, DataType);
-
-    Connect(input, layer, inputTensorInfo);
-    Connect(layer, output, outputTensorInfo);
-
-    CreateTensorHandles(graph, factory);
-
-    // Makes the workload and checks it.
-    auto workload = MakeAndCheckWorkload<SpaceToDepthWorkload>(*layer, factory);
-
-    SpaceToDepthQueueDescriptor queueDescriptor = workload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == 1);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    return workload;
-}
-
-template <typename StackWorkload, armnn::DataType DataType>
-std::unique_ptr<StackWorkload> CreateStackWorkloadTest(armnn::IWorkloadFactory& factory,
-                                                       armnn::Graph& graph,
-                                                       const armnn::TensorShape& inputShape,
-                                                       const armnn::TensorShape& outputShape,
-                                                       unsigned int axis,
-                                                       unsigned int numInputs)
-{
-    armnn::TensorInfo inputTensorInfo(inputShape, DataType);
-    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
-
-    // Constructs the Stack layer.
-    armnn::StackDescriptor descriptor(axis, numInputs, inputShape);
-    Layer* const stackLayer = graph.AddLayer<StackLayer>(descriptor, "stack");
-    CHECK(stackLayer != nullptr);
-
-    // Constructs layer inputs and output.
-    std::vector<Layer*> inputs;
-    for (unsigned int i=0; i<numInputs; ++i)
-    {
-        inputs.push_back(graph.AddLayer<InputLayer>(
-            static_cast<int>(i),
-            ("input" + std::to_string(i)).c_str()
-        ));
-        CHECK(inputs[i] != nullptr);
-    }
-    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
-    CHECK(output != nullptr);
-
-    // Adds connections.
-    for (unsigned int i=0; i<numInputs; ++i)
-    {
-        Connect(inputs[i], stackLayer, inputTensorInfo, 0, i);
-    }
-    Connect(stackLayer, output, outputTensorInfo, 0, 0);
-
-    CreateTensorHandles(graph, factory);
-
-    auto stackWorkload = MakeAndCheckWorkload<StackWorkload>(*stackLayer, factory);
-    StackQueueDescriptor queueDescriptor = stackWorkload->GetData();
-    CHECK(queueDescriptor.m_Inputs.size() == numInputs);
-    CHECK(queueDescriptor.m_Outputs.size() == 1);
-
-    return stackWorkload;
-}
-
-} // Anonymous namespace
+// This file is deprecated and will be removed soon.
+// Please use the new header in armnnTestUtils instead.
+// This will use the new armnnTestUtils header.
+#include "../../armnnTestUtils/CreateWorkload.hpp"
\ No newline at end of file
diff --git a/src/armnn/test/GraphTests.cpp b/src/armnn/test/GraphTests.cpp
index f375339..d246a08 100644
--- a/src/armnn/test/GraphTests.cpp
+++ b/src/armnn/test/GraphTests.cpp
@@ -2,7 +2,7 @@
 // Copyright © 2017 Arm Ltd. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
-#include "GraphUtils.hpp"
+#include <GraphUtils.hpp>
 
 #include <Graph.hpp>
 #include <Layer.hpp>
diff --git a/src/armnn/test/GraphUtils.hpp b/src/armnn/test/GraphUtils.hpp
index 60d03dc..02954e3 100644
--- a/src/armnn/test/GraphUtils.hpp
+++ b/src/armnn/test/GraphUtils.hpp
@@ -1,25 +1,9 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
-#pragma once
 
-#include <Graph.hpp>
+#include "../../armnnTestUtils/GraphUtils.hpp"
 
-#include <string>
-
-
-bool GraphHasNamedLayer(const armnn::Graph& graph, const std::string& name);
-
-armnn::Layer* GetFirstLayerWithName(armnn::Graph& graph, const std::string& name);
-
-bool CheckNumberOfInputSlot(armnn::Layer* layer, unsigned int num);
-
-bool CheckNumberOfOutputSlot(armnn::Layer* layer, unsigned int num);
-
-bool IsConnected(armnn::Layer* srcLayer, armnn::Layer* destLayer,
-                 unsigned int srcSlot, unsigned int destSlot,
-                 const armnn::TensorInfo& expectedTensorInfo);
-
-bool CheckOrder(const armnn::Graph& graph, const armnn::Layer* first, const armnn::Layer* second);
-
+#pragma message("src/armnn/test/GraphUtils.hpp has been deprecated, it is due for removal in 22.08 release." \
+                " Please use from armnnTestUtils library, /src/armnnTestUtils/GraphUtils.hpp)
diff --git a/src/armnn/test/InferOutputTests.cpp b/src/armnn/test/InferOutputTests.cpp
index f8d8e89..c7c0c6d 100644
--- a/src/armnn/test/InferOutputTests.cpp
+++ b/src/armnn/test/InferOutputTests.cpp
@@ -5,7 +5,7 @@
 
 #include "InferOutputTests.hpp"
 
-#include <test/UnitTests.hpp>
+#include <UnitTests.hpp>
 
 TEST_SUITE("LayerValidateOutput")
 {
diff --git a/src/armnn/test/InferOutputTests.hpp b/src/armnn/test/InferOutputTests.hpp
index 6435d87..799739b 100644
--- a/src/armnn/test/InferOutputTests.hpp
+++ b/src/armnn/test/InferOutputTests.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Graph.hpp>
 #include <layers/ArgMinMaxLayer.hpp>
diff --git a/src/armnn/test/NetworkTests.cpp b/src/armnn/test/NetworkTests.cpp
index c1927e3..d4edf5d 100644
--- a/src/armnn/test/NetworkTests.cpp
+++ b/src/armnn/test/NetworkTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "GraphUtils.hpp"
+#include <GraphUtils.hpp>
 
 #include <armnn/LayerVisitorBase.hpp>
 
diff --git a/src/armnn/test/OptimizerTests.cpp b/src/armnn/test/OptimizerTests.cpp
index 750e696..a5db0ac 100644
--- a/src/armnn/test/OptimizerTests.cpp
+++ b/src/armnn/test/OptimizerTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <BackendSettings.hpp>
 #include <Graph.hpp>
diff --git a/src/armnn/test/PredicateResult.hpp b/src/armnn/test/PredicateResult.hpp
index a344c8e..8edf8b1 100644
--- a/src/armnn/test/PredicateResult.hpp
+++ b/src/armnn/test/PredicateResult.hpp
@@ -2,47 +2,8 @@
 // Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
-#pragma once
 
-#include <sstream>
+#include <armnnTestUtils/PredicateResult.hpp>
 
-namespace armnn
-{
-
-class PredicateResult
-{
-public:
-    explicit PredicateResult(bool result)
-        : m_Result(result)
-    {}
-
-    PredicateResult(const PredicateResult& predicateResult)
-        : m_Result(predicateResult.m_Result)
-        , m_Message(predicateResult.m_Message.str())
-    {}
-
-    void SetResult(bool newResult)
-    {
-        m_Result = newResult;
-    }
-
-    std::stringstream& Message()
-    {
-        return m_Message;
-    }
-
-    bool operator!() const
-    {
-        return !m_Result;
-    }
-
-    void operator=(PredicateResult otherPredicateResult)
-    {
-        otherPredicateResult.m_Result = m_Result;
-    }
-
-    bool m_Result;
-    std::stringstream m_Message;
-};
-
-}    // namespace armnn
\ No newline at end of file
+#pragma message("src/armnn/test/PredicateResult.hpp has been deprecated, it is due for removal in 22.08 release." \
+                " Please use public interface include/armnnTestUtils/PredicateResult.hpp")
\ No newline at end of file
diff --git a/src/armnn/test/RuntimeTests.cpp b/src/armnn/test/RuntimeTests.cpp
index f055f23..045007b 100644
--- a/src/armnn/test/RuntimeTests.cpp
+++ b/src/armnn/test/RuntimeTests.cpp
@@ -22,7 +22,7 @@
 
 #include <doctest/doctest.h>
 #include "RuntimeTests.hpp"
-#include "TestUtils.hpp"
+#include <TestUtils.hpp>
 
 namespace armnn
 {
diff --git a/src/armnn/test/TensorHelpers.hpp b/src/armnn/test/TensorHelpers.hpp
index 95cea58..626cda3 100644
--- a/src/armnn/test/TensorHelpers.hpp
+++ b/src/armnn/test/TensorHelpers.hpp
@@ -1,235 +1,9 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
-#pragma once
 
-#include "PredicateResult.hpp"
-
-#include <armnn/Tensor.hpp>
-#include <armnn/utility/Assert.hpp>
-#include <armnnUtils/FloatingPointComparison.hpp>
-
-#include <QuantizeHelper.hpp>
-
-#include <doctest/doctest.h>
-
-#include <array>
-#include <cmath>
-#include <random>
-#include <vector>
-
-constexpr float g_FloatCloseToZeroTolerance = 1.0e-6f;
-
-template<typename T, bool isQuantized = true>
-struct SelectiveComparer
-{
-    static bool Compare(T a, T b)
-    {
-        return (std::max(a, b) - std::min(a, b)) <= 1;
-    }
-
-};
-
-template<typename T>
-struct SelectiveComparer<T, false>
-{
-    static bool Compare(T a, T b)
-    {
-        // If a or b is zero, percent_tolerance does an exact match, so compare to a small, constant tolerance instead.
-        if (a == 0.0f || b == 0.0f)
-        {
-            return std::abs(a - b) <= g_FloatCloseToZeroTolerance;
-        }
-
-        if (std::isinf(a) && a == b)
-        {
-            return true;
-        }
-
-        if (std::isnan(a) && std::isnan(b))
-        {
-            return true;
-        }
-
-        // For unquantized floats we use a tolerance of 1%.
-        return armnnUtils::within_percentage_tolerance(a, b);
-    }
-};
-
-template<typename T>
-bool SelectiveCompare(T a, T b)
-{
-    return SelectiveComparer<T, armnn::IsQuantizedType<T>()>::Compare(a, b);
-};
-
-template<typename T>
-bool SelectiveCompareBoolean(T a, T b)
-{
-    return (((a == 0) && (b == 0)) || ((a != 0) && (b != 0)));
-};
-
-template <typename T>
-armnn::PredicateResult CompareTensors(const std::vector<T>& actualData,
-                                      const std::vector<T>& expectedData,
-                                      const armnn::TensorShape& actualShape,
-                                      const armnn::TensorShape& expectedShape,
-                                      bool compareBoolean = false,
-                                      bool isDynamic = false)
-{
-    if (actualData.size() != expectedData.size())
-    {
-        armnn::PredicateResult res(false);
-        res.Message() << "Different data size ["
-                      << actualData.size()
-                      << "!="
-                      << expectedData.size()
-                      << "]";
-        return res;
-    }
-
-    if (actualShape.GetNumDimensions() != expectedShape.GetNumDimensions())
-    {
-        armnn::PredicateResult res(false);
-        res.Message() << "Different number of dimensions ["
-                      << actualShape.GetNumDimensions()
-                      << "!="
-                      << expectedShape.GetNumDimensions()
-                      << "]";
-        return res;
-    }
-
-    if (actualShape.GetNumElements() != expectedShape.GetNumElements())
-    {
-        armnn::PredicateResult res(false);
-        res.Message() << "Different number of elements ["
-                      << actualShape.GetNumElements()
-                      << "!="
-                      << expectedShape.GetNumElements()
-                      << "]";
-        return res;
-    }
-
-    unsigned int numberOfDimensions = actualShape.GetNumDimensions();
-
-    if (!isDynamic)
-    {
-        // Checks they are same shape.
-        for (unsigned int i = 0; i < numberOfDimensions; ++i)
-        {
-            if (actualShape[i] != expectedShape[i])
-            {
-                armnn::PredicateResult res(false);
-                res.Message() << "Different shapes ["
-                              << actualShape[i]
-                              << "!="
-                              << expectedShape[i]
-                              << "]";
-                return res;
-            }
-        }
-    }
-
-    // Fun iteration over n dimensions.
-    std::vector<unsigned int> indices;
-    for (unsigned int i = 0; i < numberOfDimensions; i++)
-    {
-        indices.emplace_back(0);
-    }
-
-    std::stringstream errorString;
-    int numFailedElements = 0;
-    constexpr int maxReportedDifferences = 3;
-    unsigned int index = 0;
-
-    // Compare data element by element.
-    while (true)
-    {
-        bool comparison;
-        // As true for uint8_t is non-zero (1-255) we must have a dedicated compare for Booleans.
-        if(compareBoolean)
-        {
-            comparison = SelectiveCompareBoolean(actualData[index], expectedData[index]);
-        }
-        else
-        {
-            comparison = SelectiveCompare(actualData[index], expectedData[index]);
-        }
-
-        if (!comparison)
-        {
-            ++numFailedElements;
-
-            if (numFailedElements <= maxReportedDifferences)
-            {
-                if (numFailedElements >= 2)
-                {
-                    errorString << ", ";
-                }
-                errorString << "[";
-                for (unsigned int i = 0; i < numberOfDimensions; ++i)
-                {
-                    errorString << indices[i];
-                    if (i != numberOfDimensions - 1)
-                    {
-                        errorString << ",";
-                    }
-                }
-                errorString << "]";
-
-                errorString << " (" << +actualData[index] << " != " << +expectedData[index] << ")";
-            }
-        }
-
-        ++indices[numberOfDimensions - 1];
-        for (unsigned int i=numberOfDimensions-1; i>0; i--)
-        {
-            if (indices[i] == actualShape[i])
-            {
-                indices[i] = 0;
-                ++indices[i - 1];
-            }
-        }
-        if (indices[0] == actualShape[0])
-        {
-            break;
-        }
-
-        index++;
-    }
-
-    armnn::PredicateResult comparisonResult(true);
-    if (numFailedElements > 0)
-    {
-        comparisonResult.SetResult(false);
-        comparisonResult.Message() << numFailedElements << " different values at: ";
-        if (numFailedElements > maxReportedDifferences)
-        {
-            errorString << ", ... (and " << (numFailedElements - maxReportedDifferences) << " other differences)";
-        }
-        comparisonResult.Message() << errorString.str();
-    }
-
-    return comparisonResult;
-}
-
-template <typename T>
-std::vector<T> MakeRandomTensor(const armnn::TensorInfo& tensorInfo,
-                                unsigned int seed,
-                                float        min = -10.0f,
-                                float        max = 10.0f)
-{
-    std::mt19937 gen(seed);
-    std::uniform_real_distribution<float> dist(min, max);
-
-    std::vector<float> init(tensorInfo.GetNumElements());
-    for (unsigned int i = 0; i < init.size(); i++)
-    {
-        init[i] = dist(gen);
-    }
-
-    const float   qScale  = tensorInfo.GetQuantizationScale();
-    const int32_t qOffset = tensorInfo.GetQuantizationOffset();
-
-    return armnnUtils::QuantizedVector<T>(init, qScale, qOffset);
-}
+// This file is deprecated and will be removed soon.
+// Please use the new header in armnnTestUtils instead.
+// This will use the new armnnTestUtils header.
+#include "../../armnnTestUtils/TensorHelpers.hpp"
\ No newline at end of file
diff --git a/src/armnn/test/TestUtils.hpp b/src/armnn/test/TestUtils.hpp
index fa9156b..fe5331e 100644
--- a/src/armnn/test/TestUtils.hpp
+++ b/src/armnn/test/TestUtils.hpp
@@ -1,58 +1,9 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
-#pragma once
+#include "../../armnnTestUtils/TestUtils.hpp"
 
-#include <armnn/INetwork.hpp>
-#include <Graph.hpp>
-#include <Runtime.hpp>
-
-void Connect(armnn::IConnectableLayer* from, armnn::IConnectableLayer* to, const armnn::TensorInfo& tensorInfo,
-             unsigned int fromIndex = 0, unsigned int toIndex = 0);
-
-template <typename LayerT>
-bool IsLayerOfType(const armnn::Layer* const layer)
-{
-    return (layer->GetType() == armnn::LayerEnumOf<LayerT>());
-}
-
-inline bool CheckSequence(const armnn::Graph::ConstIterator first, const armnn::Graph::ConstIterator last)
-{
-    return (first == last);
-}
-
-/// Checks each unary function in Us evaluates true for each correspondent layer in the sequence [first, last).
-template <typename U, typename... Us>
-bool CheckSequence(const armnn::Graph::ConstIterator first, const armnn::Graph::ConstIterator last, U&& u, Us&&... us)
-{
-    return u(*first) && CheckSequence(std::next(first), last, us...);
-}
-
-template <typename LayerT>
-bool CheckRelatedLayers(armnn::Graph& graph, const std::list<std::string>& testRelatedLayers)
-{
-    for (auto& layer : graph)
-    {
-        if (layer->GetType() == armnn::LayerEnumOf<LayerT>())
-        {
-            auto& relatedLayers = layer->GetRelatedLayerNames();
-            if (!std::equal(relatedLayers.begin(), relatedLayers.end(), testRelatedLayers.begin(),
-                            testRelatedLayers.end()))
-            {
-                return false;
-            }
-        }
-    }
-
-    return true;
-}
-
-namespace armnn
-{
-Graph& GetGraphForTesting(IOptimizedNetwork* optNetPtr);
-ModelOptions& GetModelOptionsForTesting(IOptimizedNetwork* optNetPtr);
-profiling::ProfilingService& GetProfilingService(RuntimeImpl* runtime);
-
-} // namespace armnn
\ No newline at end of file
+#pragma message("src/armnn/test/TestUtils.hpp has been deprecated, it is due for removal in 22.08 release." \
+                " Please use from armnnTestUtils library, /src/armnnTestUtils/TestUtils.hpp)
\ No newline at end of file
diff --git a/src/armnn/test/UnitTests.hpp b/src/armnn/test/UnitTests.hpp
index e4a8b96..129a766 100644
--- a/src/armnn/test/UnitTests.hpp
+++ b/src/armnn/test/UnitTests.hpp
@@ -2,187 +2,8 @@
 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
-#pragma once
 
-#include <armnn/Logging.hpp>
-#include <armnn/Utils.hpp>
-#include <reference/RefWorkloadFactory.hpp>
-#include <reference/test/RefWorkloadFactoryHelper.hpp>
+#include "../../armnnTestUtils/UnitTests.hpp"
 
-#include <backendsCommon/test/LayerTests.hpp>
-#include <backendsCommon/test/WorkloadFactoryHelper.hpp>
-
-#include "TensorHelpers.hpp"
-
-#include <doctest/doctest.h>
-
-inline void ConfigureLoggingTest()
-{
-    // Configures logging for both the ARMNN library and this test program.
-    armnn::ConfigureLogging(true, true, armnn::LogSeverity::Fatal);
-}
-
-// The following macros require the caller to have defined FactoryType, with one of the following using statements:
-//
-//      using FactoryType = armnn::RefWorkloadFactory;
-//      using FactoryType = armnn::ClWorkloadFactory;
-//      using FactoryType = armnn::NeonWorkloadFactory;
-
-/// Executes CHECK_MESSAGE on CompareTensors() return value so that the predicate_result message is reported.
-/// If the test reports itself as not supported then the tensors are not compared.
-/// Additionally this checks that the supportedness reported by the test matches the name of the test.
-/// Unsupported tests must be 'tagged' by including "UNSUPPORTED" in their name.
-/// This is useful because it clarifies that the feature being tested is not actually supported
-/// (a passed test with the name of a feature would imply that feature was supported).
-/// If support is added for a feature, the test case will fail because the name incorrectly contains UNSUPPORTED.
-/// If support is removed for a feature, the test case will fail because the name doesn't contain UNSUPPORTED.
-template <typename T, std::size_t n>
-void CompareTestResultIfSupported(const std::string& testName, const LayerTestResult<T, n>& testResult)
-{
-    bool testNameIndicatesUnsupported = testName.find("UNSUPPORTED") != std::string::npos;
-    CHECK_MESSAGE(testNameIndicatesUnsupported != testResult.m_Supported,
-                  "The test name does not match the supportedness it is reporting");
-    if (testResult.m_Supported)
-    {
-        auto result = CompareTensors(testResult.m_ActualData,
-                                     testResult.m_ExpectedData,
-                                     testResult.m_ActualShape,
-                                     testResult.m_ExpectedShape,
-                                     testResult.m_CompareBoolean);
-       CHECK_MESSAGE(result.m_Result, result.m_Message.str());
-    }
-}
-
-template <typename T, std::size_t n>
-void CompareTestResultIfSupported(const std::string& testName, const std::vector<LayerTestResult<T, n>>& testResult)
-{
-    bool testNameIndicatesUnsupported = testName.find("UNSUPPORTED") != std::string::npos;
-    for (unsigned int i = 0; i < testResult.size(); ++i)
-    {
-        CHECK_MESSAGE(testNameIndicatesUnsupported != testResult[i].m_Supported,
-                      "The test name does not match the supportedness it is reporting");
-        if (testResult[i].m_Supported)
-        {
-            auto result = CompareTensors(testResult[i].m_ActualData,
-                                         testResult[i].m_ExpectedData,
-                                         testResult[i].m_ActualShape,
-                                         testResult[i].m_ExpectedShape);
-            CHECK_MESSAGE(result.m_Result, result.m_Message.str());
-        }
-    }
-}
-
-template<typename FactoryType, typename TFuncPtr, typename... Args>
-void RunTestFunction(const char* testName, TFuncPtr testFunction, Args... args)
-{
-    std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
-    armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
-
-    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
-    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
-
-    auto testResult = (*testFunction)(workloadFactory, memoryManager, args...);
-    CompareTestResultIfSupported(testName, testResult);
-
-    armnn::ProfilerManager::GetInstance().RegisterProfiler(nullptr);
-}
-
-
-template<typename FactoryType, typename TFuncPtr, typename... Args>
-void RunTestFunctionUsingTensorHandleFactory(const char* testName, TFuncPtr testFunction, Args... args)
-{
-    std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
-    armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
-
-    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
-    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
-
-    auto tensorHandleFactory = WorkloadFactoryHelper<FactoryType>::GetTensorHandleFactory(memoryManager);
-
-    auto testResult = (*testFunction)(workloadFactory, memoryManager, tensorHandleFactory, args...);
-    CompareTestResultIfSupported(testName, testResult);
-
-    armnn::ProfilerManager::GetInstance().RegisterProfiler(nullptr);
-}
-
-#define ARMNN_SIMPLE_TEST_CASE(TestName, TestFunction) \
-    TEST_CASE(#TestName) \
-    { \
-        TestFunction(); \
-    }
-
-#define ARMNN_AUTO_TEST_CASE(TestName, TestFunction, ...) \
-    TEST_CASE(#TestName) \
-    { \
-        RunTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
-    }
-
-#define ARMNN_AUTO_TEST_FIXTURE(TestName, Fixture, TestFunction, ...) \
-    TEST_CASE_FIXTURE(Fixture, #TestName) \
-    { \
-        RunTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
-    }
-
-#define ARMNN_AUTO_TEST_CASE_WITH_THF(TestName, TestFunction, ...) \
-    TEST_CASE(#TestName) \
-    { \
-        RunTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
-    }
-
-#define ARMNN_AUTO_TEST_FIXTURE_WITH_THF(TestName, Fixture, TestFunction, ...) \
-    TEST_CASE_FIXTURE(Fixture, #TestName) \
-    { \
-        RunTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
-    }
-
-template<typename FactoryType, typename TFuncPtr, typename... Args>
-void CompareRefTestFunction(const char* testName, TFuncPtr testFunction, Args... args)
-{
-    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
-    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
-
-    armnn::RefWorkloadFactory refWorkloadFactory;
-
-    auto testResult = (*testFunction)(workloadFactory, memoryManager, refWorkloadFactory, args...);
-    CompareTestResultIfSupported(testName, testResult);
-}
-
-template<typename FactoryType, typename TFuncPtr, typename... Args>
-void CompareRefTestFunctionUsingTensorHandleFactory(const char* testName, TFuncPtr testFunction, Args... args)
-{
-    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
-    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
-
-    armnn::RefWorkloadFactory refWorkloadFactory;
-    auto tensorHandleFactory = WorkloadFactoryHelper<FactoryType>::GetTensorHandleFactory(memoryManager);
-    auto refTensorHandleFactory =
-        RefWorkloadFactoryHelper::GetTensorHandleFactory(memoryManager);
-
-    auto testResult = (*testFunction)(
-        workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, args...);
-    CompareTestResultIfSupported(testName, testResult);
-}
-
-#define ARMNN_COMPARE_REF_AUTO_TEST_CASE(TestName, TestFunction, ...) \
-    TEST_CASE(#TestName) \
-    { \
-        CompareRefTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
-    }
-
-#define ARMNN_COMPARE_REF_AUTO_TEST_CASE_WITH_THF(TestName, TestFunction, ...) \
-    TEST_CASE(#TestName) \
-    { \
-        CompareRefTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
-    }
-
-#define ARMNN_COMPARE_REF_FIXTURE_TEST_CASE(TestName, Fixture, TestFunction, ...) \
-    TEST_CASE_FIXTURE(Fixture, #TestName) \
-    { \
-        CompareRefTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
-    }
-
-#define ARMNN_COMPARE_REF_FIXTURE_TEST_CASE_WITH_THF(TestName, Fixture, TestFunction, ...) \
-    TEST_CASE_FIXTURE(Fixture, #TestName) \
-    { \
-        CompareRefTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
-    }
+#pragma message("src/armnn/test/UnitTests.hpp has been deprecated, it is due for removal in 22.08 release." \
+                " Please use from armnnTestUtils library, /src/armnnTestUtils/UnitTests.hpp)
\ No newline at end of file
diff --git a/src/armnn/test/optimizations/AddBroadcastReshapeLayerTests.cpp b/src/armnn/test/optimizations/AddBroadcastReshapeLayerTests.cpp
index 7573005..0636a00 100644
--- a/src/armnn/test/optimizations/AddBroadcastReshapeLayerTests.cpp
+++ b/src/armnn/test/optimizations/AddBroadcastReshapeLayerTests.cpp
@@ -3,8 +3,8 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../GraphUtils.hpp"
-#include "../TestUtils.hpp"
+#include <GraphUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/ConvertConstantsBFloatTests.cpp b/src/armnn/test/optimizations/ConvertConstantsBFloatTests.cpp
index 7b326fa..4aacf7f 100644
--- a/src/armnn/test/optimizations/ConvertConstantsBFloatTests.cpp
+++ b/src/armnn/test/optimizations/ConvertConstantsBFloatTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <BFloat16.hpp>
 #include <Optimizer.hpp>
diff --git a/src/armnn/test/optimizations/ConvertConstantsFloatToHalfTests.cpp b/src/armnn/test/optimizations/ConvertConstantsFloatToHalfTests.cpp
index f74ab0f..531a0dd 100644
--- a/src/armnn/test/optimizations/ConvertConstantsFloatToHalfTests.cpp
+++ b/src/armnn/test/optimizations/ConvertConstantsFloatToHalfTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 #include <Half.hpp>
diff --git a/src/armnn/test/optimizations/ConvertConstantsHalfToFloatTests.cpp b/src/armnn/test/optimizations/ConvertConstantsHalfToFloatTests.cpp
index c455152..4c453cc 100644
--- a/src/armnn/test/optimizations/ConvertConstantsHalfToFloatTests.cpp
+++ b/src/armnn/test/optimizations/ConvertConstantsHalfToFloatTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/FoldPadTests.cpp b/src/armnn/test/optimizations/FoldPadTests.cpp
index a598983..a64660f 100644
--- a/src/armnn/test/optimizations/FoldPadTests.cpp
+++ b/src/armnn/test/optimizations/FoldPadTests.cpp
@@ -5,7 +5,7 @@
 
 #include "LayersFwd.hpp"
 #include <Network.hpp>
-#include <test/TestUtils.hpp>
+#include <TestUtils.hpp>
 #include <doctest/doctest.h>
 #include <backendsCommon/TensorHandle.hpp>
 #include <Optimizer.hpp>
diff --git a/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp b/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp
index 63cd170..37d7701 100644
--- a/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp
+++ b/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/Fp32NetworkToFp16ConverterTests.cpp b/src/armnn/test/optimizations/Fp32NetworkToFp16ConverterTests.cpp
index e2ac1bd..bc88399 100644
--- a/src/armnn/test/optimizations/Fp32NetworkToFp16ConverterTests.cpp
+++ b/src/armnn/test/optimizations/Fp32NetworkToFp16ConverterTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/FuseActivationTests.cpp b/src/armnn/test/optimizations/FuseActivationTests.cpp
index 54a9d9a..99b2b80 100644
--- a/src/armnn/test/optimizations/FuseActivationTests.cpp
+++ b/src/armnn/test/optimizations/FuseActivationTests.cpp
@@ -8,8 +8,8 @@
 #include <Network.hpp>
 #include <ResolveType.hpp>
 #include <armnn/INetwork.hpp>
-#include "test/GraphUtils.hpp"
-#include <test/TestUtils.hpp>
+#include <GraphUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/armnn/test/optimizations/FuseBatchNormTests.cpp b/src/armnn/test/optimizations/FuseBatchNormTests.cpp
index 0e969c1..70cffea 100644
--- a/src/armnn/test/optimizations/FuseBatchNormTests.cpp
+++ b/src/armnn/test/optimizations/FuseBatchNormTests.cpp
@@ -8,7 +8,7 @@
 #include <Network.hpp>
 #include <ResolveType.hpp>
 #include <armnn/INetwork.hpp>
-#include <test/TestUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/armnn/test/optimizations/InsertDebugLayerTests.cpp b/src/armnn/test/optimizations/InsertDebugLayerTests.cpp
index 03d0d22..523ffcf 100644
--- a/src/armnn/test/optimizations/InsertDebugLayerTests.cpp
+++ b/src/armnn/test/optimizations/InsertDebugLayerTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/MovePermuteUpTests.cpp b/src/armnn/test/optimizations/MovePermuteUpTests.cpp
index 38a65a6..152e799 100644
--- a/src/armnn/test/optimizations/MovePermuteUpTests.cpp
+++ b/src/armnn/test/optimizations/MovePermuteUpTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/MoveTransposeUpTests.cpp b/src/armnn/test/optimizations/MoveTransposeUpTests.cpp
index 68d277a..09bf9ae 100644
--- a/src/armnn/test/optimizations/MoveTransposeUpTests.cpp
+++ b/src/armnn/test/optimizations/MoveTransposeUpTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/OptimizeConsecutiveReshapesTests.cpp b/src/armnn/test/optimizations/OptimizeConsecutiveReshapesTests.cpp
index 694b103..599b44a 100644
--- a/src/armnn/test/optimizations/OptimizeConsecutiveReshapesTests.cpp
+++ b/src/armnn/test/optimizations/OptimizeConsecutiveReshapesTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/OptimizeInverseConversionsTests.cpp b/src/armnn/test/optimizations/OptimizeInverseConversionsTests.cpp
index 4b6dfe5..1e03140 100644
--- a/src/armnn/test/optimizations/OptimizeInverseConversionsTests.cpp
+++ b/src/armnn/test/optimizations/OptimizeInverseConversionsTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/OptimizeInversePermutesTests.cpp b/src/armnn/test/optimizations/OptimizeInversePermutesTests.cpp
index 98c84d4..cfd1a23 100644
--- a/src/armnn/test/optimizations/OptimizeInversePermutesTests.cpp
+++ b/src/armnn/test/optimizations/OptimizeInversePermutesTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/PermuteAndBatchToSpaceAsDepthToSpaceTests.cpp b/src/armnn/test/optimizations/PermuteAndBatchToSpaceAsDepthToSpaceTests.cpp
index f862315..d87d3f0 100644
--- a/src/armnn/test/optimizations/PermuteAndBatchToSpaceAsDepthToSpaceTests.cpp
+++ b/src/armnn/test/optimizations/PermuteAndBatchToSpaceAsDepthToSpaceTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Network.hpp>
 #include <Optimizer.hpp>
diff --git a/src/armnn/test/optimizations/PermuteAsReshapeTests.cpp b/src/armnn/test/optimizations/PermuteAsReshapeTests.cpp
index fdd0a6d..b143078 100644
--- a/src/armnn/test/optimizations/PermuteAsReshapeTests.cpp
+++ b/src/armnn/test/optimizations/PermuteAsReshapeTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/RedirectMembersToConstantInputsTests.cpp b/src/armnn/test/optimizations/RedirectMembersToConstantInputsTests.cpp
index 46b06a5..b3f9ed8 100644
--- a/src/armnn/test/optimizations/RedirectMembersToConstantInputsTests.cpp
+++ b/src/armnn/test/optimizations/RedirectMembersToConstantInputsTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/ReduceMultipleAxesTests.cpp b/src/armnn/test/optimizations/ReduceMultipleAxesTests.cpp
index 692f371..cf1dfa0 100644
--- a/src/armnn/test/optimizations/ReduceMultipleAxesTests.cpp
+++ b/src/armnn/test/optimizations/ReduceMultipleAxesTests.cpp
@@ -3,8 +3,8 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../GraphUtils.hpp"
-#include "../TestUtils.hpp"
+#include <GraphUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <armnn/INetwork.hpp>
 
diff --git a/src/armnn/test/optimizations/SquashEqualSiblingsTests.cpp b/src/armnn/test/optimizations/SquashEqualSiblingsTests.cpp
index 069d284..e66bb75 100644
--- a/src/armnn/test/optimizations/SquashEqualSiblingsTests.cpp
+++ b/src/armnn/test/optimizations/SquashEqualSiblingsTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnn/test/optimizations/TransposeAsReshapeTests.cpp b/src/armnn/test/optimizations/TransposeAsReshapeTests.cpp
index 5d1d950..371f3ac 100644
--- a/src/armnn/test/optimizations/TransposeAsReshapeTests.cpp
+++ b/src/armnn/test/optimizations/TransposeAsReshapeTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "../TestUtils.hpp"
+#include <TestUtils.hpp>
 
 #include <Optimizer.hpp>
 
diff --git a/src/armnnDeserializer/test/ParserFlatbuffersSerializeFixture.hpp b/src/armnnDeserializer/test/ParserFlatbuffersSerializeFixture.hpp
index f460059..21809eb 100644
--- a/src/armnnDeserializer/test/ParserFlatbuffersSerializeFixture.hpp
+++ b/src/armnnDeserializer/test/ParserFlatbuffersSerializeFixture.hpp
@@ -6,7 +6,7 @@
 #pragma once
 
 #include "SchemaSerialize.hpp"
-#include "test/TensorHelpers.hpp"
+#include "TensorHelpers.hpp"
 
 #include "flatbuffers/idl.h"
 #include "flatbuffers/util.h"
diff --git a/src/armnnTestUtils/CMakeLists.txt b/src/armnnTestUtils/CMakeLists.txt
new file mode 100755
index 0000000..3738fad
--- /dev/null
+++ b/src/armnnTestUtils/CMakeLists.txt
@@ -0,0 +1,50 @@
+#
+# Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
+# SPDX-License-Identifier: MIT
+#
+
+# armnnTestUtils library provides useful test functions for backend developers.
+set(armnnTestUtils_sources)
+list(APPEND armnnTestUtils_sources
+        ../../include/armnnTestUtils/DataLayoutUtils.hpp
+        ../../include/armnnTestUtils/LayerTestResult.hpp
+        ../../include/armnnTestUtils/PredicateResult.hpp
+        ../../include/armnnTestUtils/TensorCopyUtils.hpp
+        TensorHelpers.hpp
+        CreateWorkload.hpp
+        CommonTestUtils.cpp
+        CommonTestUtils.hpp
+        DataTypeUtils.hpp
+        GraphUtils.cpp
+        GraphUtils.hpp
+        TensorCopyUtils.cpp
+        TestUtils.cpp
+        TestUtils.hpp
+        UnitTests.cpp
+        UnitTests.hpp
+        WorkloadTestUtils.hpp
+        )
+
+add_library_ex(armnnTestUtils SHARED ${armnnTestUtils_sources})
+
+set_target_properties(armnnTestUtils PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
+
+target_include_directories(armnnTestUtils
+        PUBLIC
+        $<INSTALL_INTERFACE:include>
+        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+        PRIVATE
+        ${CMAKE_CURRENT_SOURCE_DIR}/src)
+
+target_include_directories(armnnTestUtils PRIVATE ../armnn)
+target_include_directories(armnnTestUtils PRIVATE ../armnnUtils)
+target_include_directories(armnnTestUtils PRIVATE ../backends)
+target_include_directories(armnnTestUtils PRIVATE ../profiling)
+
+install(TARGETS armnnTestUtils
+        EXPORT  armnn-targets
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_library(Armnn::armnnTestUtils ALIAS armnnTestUtils)
\ No newline at end of file
diff --git a/src/backends/backendsCommon/test/CommonTestUtils.cpp b/src/armnnTestUtils/CommonTestUtils.cpp
similarity index 96%
rename from src/backends/backendsCommon/test/CommonTestUtils.cpp
rename to src/armnnTestUtils/CommonTestUtils.cpp
index 287c71e..c853305 100644
--- a/src/backends/backendsCommon/test/CommonTestUtils.cpp
+++ b/src/armnnTestUtils/CommonTestUtils.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
diff --git a/src/armnnTestUtils/CommonTestUtils.hpp b/src/armnnTestUtils/CommonTestUtils.hpp
new file mode 100644
index 0000000..a4babc5
--- /dev/null
+++ b/src/armnnTestUtils/CommonTestUtils.hpp
@@ -0,0 +1,119 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include "TestUtils.hpp"
+
+#include <Graph.hpp>
+#include <SubgraphView.hpp>
+#include <SubgraphViewSelector.hpp>
+#include <ResolveType.hpp>
+
+#include <armnn/BackendRegistry.hpp>
+
+#include <armnn/Types.hpp>
+#include <backendsCommon/TensorHandle.hpp>
+
+#include <algorithm>
+#include <random>
+#include <vector>
+
+// Checks that two collections have the exact same contents (in any order)
+// The given collections do not have to contain duplicates
+// Cannot use std::sort here because std lists have their own std::list::sort method
+template <typename CollectionType>
+bool AreEqual(const CollectionType& lhs, const CollectionType& rhs)
+{
+    if (lhs.size() != rhs.size())
+    {
+        return false;
+    }
+
+    auto lhs_it = std::find_if(lhs.begin(), lhs.end(), [&rhs](auto& item)
+    {
+        return std::find(rhs.begin(), rhs.end(), item) == rhs.end();
+    });
+
+    return lhs_it == lhs.end();
+}
+
+// Checks that the given collection contains the specified item
+template <typename CollectionType>
+bool Contains(const CollectionType& collection, const typename CollectionType::value_type& item)
+{
+    return std::find(collection.begin(), collection.end(), item) != collection.end();
+}
+
+// Checks that the given map contains the specified key
+template <typename MapType>
+bool Contains(const MapType& map, const typename MapType::key_type& key)
+{
+    return map.find(key) != map.end();
+}
+
+// Utility template for comparing tensor elements
+template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
+inline bool Compare(T a, T b, float tolerance = 0.000001f)
+{
+    if (ArmnnType == armnn::DataType::Boolean)
+    {
+        // NOTE: Boolean is represented as uint8_t (with zero equals
+        // false and everything else equals true), therefore values
+        // need to be casted to bool before comparing them
+        return static_cast<bool>(a) == static_cast<bool>(b);
+    }
+
+    // NOTE: All other types can be cast to float and compared with
+    // a certain level of tolerance
+    return std::fabs(static_cast<float>(a) - static_cast<float>(b)) <= tolerance;
+}
+
+template <typename ConvolutionLayer>
+void SetWeightAndBias(ConvolutionLayer* layer, const armnn::TensorInfo& weightInfo, const armnn::TensorInfo& biasInfo)
+{
+    layer->m_Weight = std::make_unique<armnn::ScopedTensorHandle>(weightInfo);
+    layer->m_Bias   = std::make_unique<armnn::ScopedTensorHandle>(biasInfo);
+
+    layer->m_Weight->Allocate();
+    layer->m_Bias->Allocate();
+}
+
+armnn::SubgraphView::InputSlots CreateInputsFrom(const std::vector<armnn::Layer*>& layers);
+
+armnn::SubgraphView::OutputSlots CreateOutputsFrom(const std::vector<armnn::Layer*>& layers);
+
+armnn::SubgraphView::SubgraphViewPtr CreateSubgraphViewFrom(armnn::SubgraphView::InputSlots&& inputs,
+                                                            armnn::SubgraphView::OutputSlots&& outputs,
+                                                            armnn::SubgraphView::Layers&& layers);
+
+armnn::IBackendInternalUniquePtr CreateBackendObject(const armnn::BackendId& backendId);
+
+armnn::TensorShape MakeTensorShape(unsigned int batches,
+                                   unsigned int channels,
+                                   unsigned int height,
+                                   unsigned int width,
+                                   armnn::DataLayout layout);
+
+template<typename DataType>
+static std::vector<DataType> GenerateRandomData(size_t size)
+{
+    constexpr bool isIntegerType = std::is_integral<DataType>::value;
+    using Distribution =
+    typename std::conditional<isIntegerType,
+            std::uniform_int_distribution<DataType>,
+            std::uniform_real_distribution<DataType>>::type;
+
+    static constexpr DataType lowerLimit = std::numeric_limits<DataType>::min();
+    static constexpr DataType upperLimit = std::numeric_limits<DataType>::max();
+
+    static Distribution distribution(lowerLimit, upperLimit);
+    static std::default_random_engine generator;
+
+    std::vector<DataType> randomData(size);
+    generate(randomData.begin(), randomData.end(), []() { return distribution(generator); });
+
+    return randomData;
+}
diff --git a/src/armnnTestUtils/CreateWorkload.hpp b/src/armnnTestUtils/CreateWorkload.hpp
new file mode 100644
index 0000000..ea8a436
--- /dev/null
+++ b/src/armnnTestUtils/CreateWorkload.hpp
@@ -0,0 +1,2316 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include "TestUtils.hpp"
+
+#include <Graph.hpp>
+#include <Network.hpp>
+#include <ResolveType.hpp>
+
+#include <armnnUtils/DataLayoutIndexed.hpp>
+#include <armnn/utility/Assert.hpp>
+#include <armnn/utility/IgnoreUnused.hpp>
+#include <armnn/utility/PolymorphicDowncast.hpp>
+
+#include <backendsCommon/TensorHandle.hpp>
+#include <backendsCommon/WorkloadData.hpp>
+#include <backendsCommon/WorkloadFactory.hpp>
+
+#include <doctest/doctest.h>
+
+#include <utility>
+
+using namespace armnn;
+
+namespace
+{
+
+using namespace std;
+
+// Calls CreateWorkload for a layer, and checks the returned pointer is of the correct type.
+template<typename Workload>
+std::unique_ptr<Workload> MakeAndCheckWorkload(Layer& layer,
+                                               const IWorkloadFactory& factory,
+                                               const ModelOptions& modelOptions = {})
+{
+    std::unique_ptr<IWorkload> workload = layer.CreateWorkload(factory);
+    CHECK_MESSAGE(workload.get() == PolymorphicDowncast<Workload*>(workload.get()),
+               "Cannot convert to derived class");
+    std::string reasonIfUnsupported;
+    layer.SetBackendId(factory.GetBackendId());
+    CHECK(factory.IsLayerSupported(layer, layer.GetDataType(), reasonIfUnsupported, modelOptions));
+    return std::unique_ptr<Workload>(static_cast<Workload*>(workload.release()));
+}
+
+// Helper function to create tensor handlers for workloads, assuming they all use the same factory.
+void CreateTensorHandles(armnn::Graph& graph,
+                         armnn::IWorkloadFactory& factory)
+{
+    TensorHandleFactoryRegistry tmpRegistry;
+    for (auto&& layer : graph.TopologicalSort())
+    {
+        layer->CreateTensorHandles(tmpRegistry, factory);
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// The following functions are called by backendsCommon/test/CreateWorkload*.cpp
+// They build very simple graphs, and then create a workload.
+// Some checks are performed on the workload to ensure parameters have been passed correctly.
+// They return the created workloads so that backend-specific checks can be performed.
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+template <typename ActivationWorkload, armnn::DataType DataType>
+std::unique_ptr<ActivationWorkload> CreateActivationWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                 armnn::Graph&            graph)
+{
+    // Creates the layer we're testing.
+    ActivationDescriptor layerDesc;
+    layerDesc.m_Function = ActivationFunction::Abs;
+    layerDesc.m_A        = 3.5f;
+    layerDesc.m_B        = -10.0f;
+
+    ActivationLayer* const layer = graph.AddLayer<ActivationLayer>(layerDesc, "layer");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo({1, 1}, DataType);
+
+    Connect(input, layer, tensorInfo);
+    Connect(layer, output, tensorInfo);
+
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<ActivationWorkload>(*layer, factory);
+
+    ActivationQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK(queueDescriptor.m_Parameters.m_A == 3.5f);
+    CHECK(queueDescriptor.m_Parameters.m_B == -10.0f);
+    CHECK((queueDescriptor.m_Parameters.m_Function == ActivationFunction::Abs));
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename WorkloadType,
+          typename DescriptorType,
+          typename LayerType,
+          armnn::DataType DataType>
+std::unique_ptr<WorkloadType> CreateElementwiseWorkloadTest(armnn::IWorkloadFactory & factory,
+                                                            armnn::Graph & graph)
+{
+    // Creates the layer we're testing.
+    Layer* const layer = graph.AddLayer<LayerType>("layer");
+
+    // Creates extra layers.
+    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
+    Layer* const input2 = graph.AddLayer<InputLayer>(2, "input2");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo({2, 3}, DataType);
+    Connect(input1, layer, tensorInfo, 0, 0);
+    Connect(input2, layer, tensorInfo, 0, 1);
+    Connect(layer, output, tensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
+
+    DescriptorType queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 2);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template<typename WorkloadType,
+         typename DescriptorType,
+         armnn::DataType DataType>
+std::unique_ptr<WorkloadType> CreateSubtractionWithBlobWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                    armnn::Graph& graph)
+{
+    // Creates the layer we're testing.
+    SubtractionLayer* const layer = graph.AddLayer<SubtractionLayer>("layer");
+
+    auto activationDesc = std::make_shared<ActivationDescriptor>();
+    activationDesc->m_A        = 10.0f;
+    activationDesc->m_B        = 5.0f;
+    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
+
+    layer->SetAdditionalInfoForObject(activationDesc);
+
+    // Creates extra layers.
+    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
+    Layer* const input2 = graph.AddLayer<InputLayer>(2, "input2");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo({2, 3}, DataType);
+    Connect(input1, layer, tensorInfo, 0, 0);
+    Connect(input2, layer, tensorInfo, 0, 1);
+    Connect(layer, output, tensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Check that the additional information can be queried from the layer
+    std::shared_ptr<ActivationDescriptor>
+        activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
+
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
+
+    DescriptorType queueDescriptor = workload->GetData();
+
+    const ActivationDescriptor* queueDescBlobPtr =
+        queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
+    IgnoreUnused(queueDescBlobPtr);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    CHECK(queueDescriptor.m_Inputs.size() == 2);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    return workload;
+}
+
+template<typename WorkloadType,
+         typename DescriptorType,
+         armnn::DataType DataType>
+std::unique_ptr<WorkloadType> CreateMultiplicationWithBlobWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                       armnn::Graph& graph)
+{
+    // Creates the layer we're testing.
+    MultiplicationLayer* const layer = graph.AddLayer<MultiplicationLayer>("layer");
+
+    auto activationDesc = std::make_shared<ActivationDescriptor>();
+    activationDesc->m_A        = 10.0f;
+    activationDesc->m_B        = 5.0f;
+    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
+
+    layer->SetAdditionalInfoForObject(activationDesc);
+
+    // Creates extra layers.
+    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
+    Layer* const input2 = graph.AddLayer<InputLayer>(2, "input2");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo({2, 3}, DataType);
+    Connect(input1, layer, tensorInfo, 0, 0);
+    Connect(input2, layer, tensorInfo, 0, 1);
+    Connect(layer, output, tensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Check that the additional information can be queried from the layer
+    std::shared_ptr<ActivationDescriptor>
+        activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
+
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
+
+    DescriptorType queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 2);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    const ActivationDescriptor* queueDescBlobPtr =
+        queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
+    IgnoreUnused(queueDescBlobPtr);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    return workload;// Returns so we can do extra, backend-specific tests.
+}
+
+template<typename WorkloadType,
+         typename DescriptorType,
+         armnn::DataType DataType>
+std::unique_ptr<WorkloadType> CreateAdditionWithBlobWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                 armnn::Graph& graph)
+{
+    // Creates the layer we're testing.
+    AdditionLayer* const layer = graph.AddLayer<AdditionLayer>("layer");
+
+    auto activationDesc = std::make_shared<ActivationDescriptor>();
+    activationDesc->m_A        = 10.0f;
+    activationDesc->m_B        = 5.0f;
+    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
+
+    layer->SetAdditionalInfoForObject(activationDesc);
+
+    // Creates extra layers.
+    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
+    Layer* const input2 = graph.AddLayer<InputLayer>(2, "input2");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo({2, 3}, DataType);
+    Connect(input1, layer, tensorInfo, 0, 0);
+    Connect(input2, layer, tensorInfo, 0, 1);
+    Connect(layer, output, tensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Check that the additional information can be queried from the layer
+    std::shared_ptr<ActivationDescriptor>
+        activationDescPtr = layer->template GetAdditionalInformation<ActivationDescriptor>();
+
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
+
+    DescriptorType queueDescriptor = workload->GetData();
+    const ActivationDescriptor* queueDescBlobPtr =
+        queueDescriptor.template GetAdditionalInformation<ActivationDescriptor>();
+    IgnoreUnused(queueDescBlobPtr);
+    CHECK(queueDescriptor.m_Inputs.size() == 2);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    return workload;
+}
+
+template <typename WorkloadType,
+          typename DescriptorType,
+          armnn::DataType DataType>
+std::unique_ptr<WorkloadType> CreateElementwiseUnaryWorkloadTest(armnn::IWorkloadFactory & factory,
+                                                                 armnn::Graph & graph,
+                                                                 armnn::UnaryOperation op)
+{
+    ElementwiseUnaryDescriptor desc = ElementwiseUnaryDescriptor(op);
+    Layer* const layer = graph.AddLayer<armnn::ElementwiseUnaryLayer>(desc, "layer");
+
+    Layer* const input  = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    armnn::TensorInfo tensorInfo({ 2, 3 }, DataType);
+    Connect(input, layer, tensorInfo, 0, 0);
+    Connect(layer, output, tensorInfo, 0, 0);
+    CreateTensorHandles(graph, factory);
+
+    auto workload = MakeAndCheckWorkload<WorkloadType>(*layer, factory);
+    DescriptorType queueDescriptor = workload->GetData();
+
+    CHECK(queueDescriptor.m_Inputs.size()  == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    return workload;
+}
+
+template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
+std::unique_ptr<BatchNormalizationWorkloadType> CreateBatchNormalizationWorkloadTest(
+    armnn::IWorkloadFactory& factory, armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW)
+{
+    TensorShape tensorShape;
+    switch (dataLayout)
+    {
+        case DataLayout::NHWC:
+            tensorShape = { 2, 4, 4, 3 };
+            break;
+        case DataLayout::NCHW:
+        default:
+            tensorShape = { 2, 3, 4, 4 };
+    }
+
+    // Creates the layer we're testing.
+    BatchNormalizationDescriptor layerDesc;
+    layerDesc.m_Eps = 0.05f;
+    layerDesc.m_DataLayout = dataLayout;
+
+    BatchNormalizationLayer* const layer = graph.AddLayer<BatchNormalizationLayer>(layerDesc, "layer");
+
+    armnn::TensorInfo weightInfo({3}, DataType);
+    layer->m_Mean     = std::make_unique<ScopedTensorHandle>(weightInfo);
+    layer->m_Variance = std::make_unique<ScopedTensorHandle>(weightInfo);
+    layer->m_Beta     = std::make_unique<ScopedTensorHandle>(weightInfo);
+    layer->m_Gamma    = std::make_unique<ScopedTensorHandle>(weightInfo);
+    layer->m_Mean->Allocate();
+    layer->m_Variance->Allocate();
+    layer->m_Beta->Allocate();
+    layer->m_Gamma->Allocate();
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo(tensorShape, DataType);
+    Connect(input, layer, tensorInfo);
+    Connect(layer, output, tensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<BatchNormalizationWorkloadType>(*layer, factory);
+    BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_Eps == 0.05f);
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK((queueDescriptor.m_Mean->GetTensorInfo() == TensorInfo({3}, DataType)));
+    CHECK((queueDescriptor.m_Variance->GetTensorInfo() == TensorInfo({3}, DataType)));
+    CHECK((queueDescriptor.m_Gamma->GetTensorInfo() == TensorInfo({3}, DataType)));
+    CHECK((queueDescriptor.m_Beta->GetTensorInfo() == TensorInfo({3}, DataType)));
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
+std::unique_ptr<BatchNormalizationWorkloadType> CreateBatchNormalizationWithBlobWorkloadTest(
+    armnn::IWorkloadFactory& factory, armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW)
+{
+    TensorShape tensorShape;
+    switch (dataLayout)
+    {
+        case DataLayout::NHWC:
+            tensorShape = { 2, 4, 4, 3 };
+            break;
+        case DataLayout::NCHW:
+        default:
+            tensorShape = { 2, 3, 4, 4 };
+    }
+
+    // Creates the layer we're testing.
+    BatchNormalizationDescriptor layerDesc;
+    layerDesc.m_Eps = 0.05f;
+    layerDesc.m_DataLayout = dataLayout;
+
+    BatchNormalizationLayer* const layer = graph.AddLayer<BatchNormalizationLayer>(layerDesc, "layer");
+
+    armnn::TensorInfo weightInfo({3}, DataType);
+    layer->m_Mean     = std::make_unique<ScopedTensorHandle>(weightInfo);
+    layer->m_Variance = std::make_unique<ScopedTensorHandle>(weightInfo);
+    layer->m_Beta     = std::make_unique<ScopedTensorHandle>(weightInfo);
+    layer->m_Gamma    = std::make_unique<ScopedTensorHandle>(weightInfo);
+    layer->m_Mean->Allocate();
+    layer->m_Variance->Allocate();
+    layer->m_Beta->Allocate();
+    layer->m_Gamma->Allocate();
+
+    auto activationDesc = std::make_shared<ActivationDescriptor>();
+    activationDesc->m_A        = 10.0f;
+    activationDesc->m_B        = 5.0f;
+    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
+
+    layer->SetAdditionalInfoForObject(activationDesc);
+
+    // Check that the additional information can be queried from the layer
+    std::shared_ptr<ActivationDescriptor> activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo(tensorShape, DataType);
+    Connect(input, layer, tensorInfo);
+    Connect(layer, output, tensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<BatchNormalizationWorkloadType>(*layer, factory);
+    BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
+    const ActivationDescriptor* queueDescBlobPtr = queueDescriptor.GetAdditionalInformation<ActivationDescriptor>();
+    IgnoreUnused(queueDescBlobPtr);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    CHECK(queueDescriptor.m_Parameters.m_Eps == 0.05f);
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK((queueDescriptor.m_Mean->GetTensorInfo() == TensorInfo({3}, DataType)));
+    CHECK((queueDescriptor.m_Variance->GetTensorInfo() == TensorInfo({3}, DataType)));
+    CHECK((queueDescriptor.m_Gamma->GetTensorInfo() == TensorInfo({3}, DataType)));
+    CHECK((queueDescriptor.m_Beta->GetTensorInfo() == TensorInfo({3}, DataType)));
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename Convolution2dWorkload, armnn::DataType DataType>
+std::unique_ptr<Convolution2dWorkload> CreateConvolution2dWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                       armnn::Graph&            graph,
+                                                                       DataLayout dataLayout = DataLayout::NCHW,
+                                                                       const ModelOptions& modelOptions = {})
+{
+    // Creates the layer we're testing.
+    Convolution2dDescriptor layerDesc;
+    layerDesc.m_PadLeft = 3;
+    layerDesc.m_PadRight = 3;
+    layerDesc.m_PadTop = 1;
+    layerDesc.m_PadBottom = 1;
+    layerDesc.m_StrideX = 2;
+    layerDesc.m_StrideY = 4;
+    layerDesc.m_BiasEnabled = true;
+    layerDesc.m_DataLayout = dataLayout;
+
+    Convolution2dLayer* const layer = graph.AddLayer<Convolution2dLayer>(layerDesc, "layer");
+
+    TensorShape weightShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 5, 3} : TensorShape{2, 5, 3, 3};
+    TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
+    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
+
+    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo(weightShape, DataType));
+    layer->m_Bias   = std::make_unique<ScopedTensorHandle>(TensorInfo({2}, GetBiasDataType(DataType)));
+
+    layer->m_Weight->Allocate();
+    layer->m_Bias->Allocate();
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    Connect(input, layer, TensorInfo(inputShape, DataType));
+    Connect(layer, output, TensorInfo(outputShape, DataType));
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
+
+    Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
+    CHECK(queueDescriptor.m_Parameters.m_StrideY == 4);
+    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 3);
+    CHECK(queueDescriptor.m_Parameters.m_PadRight == 3);
+    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
+    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled);
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType)));
+    CHECK((queueDescriptor.m_Bias->GetTensorInfo() ==
+        TensorInfo({2}, GetBiasDataType(DataType))));
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template<typename Convolution2dWorkload, armnn::DataType DataType>
+std::unique_ptr<Convolution2dWorkload> CreateConvolution2dFusedActivationWithBlobWorkloadTest(
+    armnn::IWorkloadFactory& factory,
+    armnn::Graph& graph,
+    DataLayout dataLayout = DataLayout::NCHW,
+    const ModelOptions& modelOptions = {})
+{
+    // Creates the layer we're testing.
+    Convolution2dDescriptor layerDesc;
+    layerDesc.m_PadLeft = 3;
+    layerDesc.m_PadRight = 3;
+    layerDesc.m_PadTop = 1;
+    layerDesc.m_PadBottom = 1;
+    layerDesc.m_StrideX = 2;
+    layerDesc.m_StrideY = 4;
+    layerDesc.m_BiasEnabled = true;
+    layerDesc.m_DataLayout = dataLayout;
+
+
+    Convolution2dLayer* const layer = graph.AddLayer<Convolution2dLayer>(layerDesc, "layer");
+
+    TensorShape weightShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 5, 3} : TensorShape{2, 5, 3, 3};
+    TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
+    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
+
+    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo(weightShape, DataType));
+    layer->m_Bias   = std::make_unique<ScopedTensorHandle>(TensorInfo({2}, GetBiasDataType(DataType)));
+
+    layer->m_Weight->Allocate();
+    layer->m_Bias->Allocate();
+
+    auto activationDesc = std::make_shared<ActivationDescriptor>();
+    activationDesc->m_A        = 10.0f;
+    activationDesc->m_B        = 5.0f;
+    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
+
+    layer->SetAdditionalInfoForObject(activationDesc);
+
+    // Check that the additional information can be queried from the layer
+    std::shared_ptr<ActivationDescriptor> activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
+
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(activationDescPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    Connect(input, layer, TensorInfo(inputShape, DataType));
+    Connect(layer, output, TensorInfo(outputShape, DataType));
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
+
+    Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
+    const ActivationDescriptor* queueDescBlobPtr = queueDescriptor.GetAdditionalInformation<ActivationDescriptor>();
+    IgnoreUnused(queueDescBlobPtr);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
+    CHECK(queueDescriptor.m_Parameters.m_StrideY == 4);
+    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 3);
+    CHECK(queueDescriptor.m_Parameters.m_PadRight == 3);
+    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
+    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled);
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType)));
+    CHECK((queueDescriptor.m_Bias->GetTensorInfo() ==
+        TensorInfo({2}, GetBiasDataType(DataType))));
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename Convolution2dWorkload, armnn::DataType DataType>
+std::unique_ptr<Convolution2dWorkload> CreateConvolution2dWorkloadFastMathTest(armnn::IWorkloadFactory& factory,
+                                                                               armnn::Graph&            graph,
+                                                                               DataLayout dataLayout = DataLayout::NCHW,
+                                                                               const ModelOptions& modelOptions = {})
+{
+    // Creates the layer we're testing.
+    Convolution2dDescriptor layerDesc;
+    layerDesc.m_PadLeft = 0;
+    layerDesc.m_PadRight = 0;
+    layerDesc.m_PadTop = 0;
+    layerDesc.m_PadBottom = 0;
+    layerDesc.m_StrideX = 1;
+    layerDesc.m_StrideY = 1;
+    layerDesc.m_BiasEnabled = false;
+    layerDesc.m_DataLayout = dataLayout;
+
+    Convolution2dLayer* const layer = graph.AddLayer<Convolution2dLayer>(layerDesc, "layer");
+
+    TensorShape weightShape = TensorShape{32, 32, 3, 3};
+    TensorShape inputShape  = TensorShape{1, 32, 149, 149};
+    TensorShape outputShape = TensorShape{1, 32, 147, 147};
+
+    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo(weightShape, DataType));
+    layer->m_Bias   = std::make_unique<ScopedTensorHandle>(TensorInfo({2}, GetBiasDataType(DataType)));
+
+    layer->m_Weight->Allocate();
+    layer->m_Bias->Allocate();
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    Connect(input, layer, TensorInfo(inputShape, DataType));
+    Connect(layer, output, TensorInfo(outputShape, DataType));
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory, modelOptions);
+
+    Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
+    CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 0);
+    CHECK(queueDescriptor.m_Parameters.m_PadRight == 0);
+    CHECK(queueDescriptor.m_Parameters.m_PadTop == 0);
+    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 0);
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo(weightShape, DataType)));
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename LstmWorkload>
+std::unique_ptr<LstmWorkload> CreateLstmWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph)
+{
+    // This parameter setting is for withCifgWithPeepholeNoProjection
+    LstmDescriptor layerDesc;
+    layerDesc.m_ActivationFunc = 4;
+    layerDesc.m_ClippingThresCell = 0.0f;
+    layerDesc.m_ClippingThresProj = 0.0f;
+    layerDesc.m_CifgEnabled = true;
+    layerDesc.m_PeepholeEnabled = true;
+    layerDesc.m_ProjectionEnabled = false;
+
+    LstmLayer* const layer = graph.AddLayer<LstmLayer>(layerDesc, "layer");
+    unsigned int batchSize = 2;
+    unsigned int inputSize = 2;
+    unsigned int numUnits = 4;
+    unsigned int outputSize = 4;
+
+    layer->m_BasicParameters.m_InputToForgetWeights = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits, inputSize }, DataType::Float32));
+    layer->m_BasicParameters.m_InputToCellWeights = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits, inputSize }, DataType::Float32));
+    layer->m_BasicParameters.m_InputToOutputWeights = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits, inputSize }, DataType::Float32));
+    layer->m_BasicParameters.m_RecurrentToForgetWeights = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits, outputSize }, DataType::Float32));
+    layer->m_BasicParameters.m_RecurrentToCellWeights = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits, outputSize }, DataType::Float32));
+    layer->m_BasicParameters.m_RecurrentToOutputWeights = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits, outputSize }, DataType::Float32));
+    layer->m_BasicParameters.m_ForgetGateBias = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits }, DataType::Float32));
+    layer->m_BasicParameters.m_CellBias = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits }, DataType::Float32));
+    layer->m_BasicParameters.m_OutputGateBias = std::make_unique<ScopedTensorHandle>
+            (TensorInfo({ numUnits }, DataType::Float32));
+
+    layer->m_BasicParameters.m_InputToForgetWeights->Allocate();
+    layer->m_BasicParameters.m_InputToCellWeights->Allocate();
+    layer->m_BasicParameters.m_InputToOutputWeights->Allocate();
+    layer->m_BasicParameters.m_RecurrentToForgetWeights->Allocate();
+    layer->m_BasicParameters.m_RecurrentToCellWeights->Allocate();
+    layer->m_BasicParameters.m_RecurrentToOutputWeights->Allocate();
+    layer->m_BasicParameters.m_ForgetGateBias->Allocate();
+    layer->m_BasicParameters.m_CellBias->Allocate();
+    layer->m_BasicParameters.m_OutputGateBias->Allocate();
+
+
+    if (layerDesc.m_PeepholeEnabled)
+    {
+        layer->m_PeepholeParameters.m_CellToForgetWeights = std::make_unique<ScopedTensorHandle>
+                (TensorInfo({ numUnits }, DataType::Float32));
+        layer->m_PeepholeParameters.m_CellToOutputWeights = std::make_unique<ScopedTensorHandle>
+                (TensorInfo({ numUnits }, DataType::Float32));
+        layer->m_PeepholeParameters.m_CellToForgetWeights->Allocate();
+        layer->m_PeepholeParameters.m_CellToOutputWeights->Allocate();
+    }
+
+    // create input and output layers
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const outputStateIn = graph.AddLayer<InputLayer>(1, "outputStateIn");
+    Layer* const cellStateIn = graph.AddLayer<InputLayer>(2, "cellStateIn");
+    Layer* const scratchBuffer = graph.AddLayer<OutputLayer>(0, "scratchBuffer");
+    Layer* const outputStateOut = graph.AddLayer<OutputLayer>(1, "outputStateOut");
+    Layer* const cellStateOut = graph.AddLayer<OutputLayer>(2, "cellStateOut");
+    Layer* const output = graph.AddLayer<OutputLayer>(3, "output");
+
+    // connect up
+    armnn::TensorInfo lstmTensorInfo1({ batchSize, inputSize }, DataType::Float32);
+    armnn::TensorInfo lstmTensorInfo2({ batchSize, numUnits}, DataType::Float32);
+    armnn::TensorInfo lstmTensorInfo3({ batchSize, outputSize }, DataType::Float32);
+    armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * (layerDesc.m_CifgEnabled ? 3 : 4) },
+                                                DataType::Float32);
+    Connect(input, layer, lstmTensorInfo1, 0, 0);
+    Connect(cellStateIn, layer, lstmTensorInfo2, 0, 1);
+    Connect(outputStateIn, layer, lstmTensorInfo3, 0, 2);
+    Connect(layer, scratchBuffer, lstmTensorInfoScratchBuff, 0, 0);
+    Connect(layer, outputStateOut, lstmTensorInfo3, 1, 0);
+    Connect(layer, cellStateOut, lstmTensorInfo2, 2, 0);
+    Connect(layer, output, lstmTensorInfo3, 3, 0);
+
+    CreateTensorHandles(graph, factory);
+
+    // make the workload and check it
+    auto workload = MakeAndCheckWorkload<LstmWorkload>(*layer, factory);
+    LstmQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_ActivationFunc == 4);
+    CHECK(queueDescriptor.m_Parameters.m_ClippingThresCell == 0.0f);
+    CHECK(queueDescriptor.m_Parameters.m_ClippingThresProj == 0.0f);
+    CHECK(queueDescriptor.m_Inputs.size() == 3);
+    CHECK(queueDescriptor.m_Outputs.size() == 4);
+
+    CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == TensorInfo({ numUnits, inputSize },
+                                                                                     DataType::Float32)));
+    CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() == TensorInfo({ numUnits },
+                                                                                     DataType::Float32)));
+    CHECK((queueDescriptor.m_CellBias->GetTensorInfo() == TensorInfo({ numUnits }, DataType::Float32)));
+    return workload;
+}
+
+template <typename QuantizedLstmWorkload>
+std::unique_ptr<QuantizedLstmWorkload> CreateQuantizedLstmWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                       armnn::Graph& graph)
+{
+    auto layer = graph.AddLayer<QuantizedLstmLayer>("quantizedLstmlayer");
+    unsigned int numBatches = 2;
+    unsigned int inputSize = 2;
+    unsigned int outputSize = 4;
+
+    // Scale/Offset for input/output, cellState In/Out, weights, bias
+    float inputOutputScale = 0.0078125f;
+    int32_t inputOutputOffset = 128;
+
+    float cellStateScale = 0.00048828125f;
+    int32_t cellStateOffset = 0;
+
+    float weightsScale = 0.00408021f;
+    int32_t weightsOffset = 100;
+
+    float biasScale = 3.1876640625e-05f;
+    int32_t biasOffset = 0;
+
+    // Weights and bias tensor and quantization info
+    armnn::TensorInfo inputWeightsInfo({outputSize, inputSize},
+                                       armnn::DataType::QAsymmU8,
+                                       weightsScale,
+                                       weightsOffset);
+
+    armnn::TensorInfo recurrentWeightsInfo({outputSize, outputSize},
+                                           armnn::DataType::QAsymmU8,
+                                           weightsScale,
+                                           weightsOffset);
+
+    armnn::TensorInfo biasInfo({outputSize},
+                               armnn::DataType::Signed32,
+                               biasScale,
+                               biasOffset);
+
+    // Weights and bias
+    layer->m_QuantizedLstmParameters.m_InputToInputWeights =
+            std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
+    layer->m_QuantizedLstmParameters.m_InputToForgetWeights =
+            std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
+    layer->m_QuantizedLstmParameters.m_InputToCellWeights =
+            std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
+    layer->m_QuantizedLstmParameters.m_InputToOutputWeights =
+            std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
+
+    layer->m_QuantizedLstmParameters.m_RecurrentToInputWeights =
+            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
+    layer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights =
+            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
+    layer->m_QuantizedLstmParameters.m_RecurrentToCellWeights =
+            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
+    layer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights =
+            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
+
+    layer->m_QuantizedLstmParameters.m_InputGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
+    layer->m_QuantizedLstmParameters.m_ForgetGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
+    layer->m_QuantizedLstmParameters.m_CellBias = std::make_unique<ScopedTensorHandle>(biasInfo);
+    layer->m_QuantizedLstmParameters.m_OutputGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
+
+    // Allocate weights and bias
+    layer->m_QuantizedLstmParameters.m_InputToInputWeights->Allocate();
+    layer->m_QuantizedLstmParameters.m_InputToForgetWeights->Allocate();
+    layer->m_QuantizedLstmParameters.m_InputToCellWeights->Allocate();
+    layer->m_QuantizedLstmParameters.m_InputToOutputWeights->Allocate();
+
+    layer->m_QuantizedLstmParameters.m_RecurrentToInputWeights->Allocate();
+    layer->m_QuantizedLstmParameters.m_RecurrentToForgetWeights->Allocate();
+    layer->m_QuantizedLstmParameters.m_RecurrentToCellWeights->Allocate();
+    layer->m_QuantizedLstmParameters.m_RecurrentToOutputWeights->Allocate();
+
+    layer->m_QuantizedLstmParameters.m_InputGateBias->Allocate();
+    layer->m_QuantizedLstmParameters.m_ForgetGateBias->Allocate();
+    layer->m_QuantizedLstmParameters.m_CellBias->Allocate();
+    layer->m_QuantizedLstmParameters.m_OutputGateBias->Allocate();
+
+    // Create input and output layers
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const cellStateIn = graph.AddLayer<InputLayer>(1, "cellStateIn");
+    Layer* const outputStateIn = graph.AddLayer<InputLayer>(2, "outputStateIn");
+
+    Layer* const cellStateOut = graph.AddLayer<OutputLayer>(0, "cellStateOut");
+    Layer* const outputStateOut = graph.AddLayer<OutputLayer>(1, "outputStateOut");
+
+    // Input/output tensor info and quantization info
+    armnn::TensorInfo inputInfo({numBatches , inputSize},
+                                armnn::DataType::QAsymmU8,
+                                inputOutputScale,
+                                inputOutputOffset);
+
+    armnn::TensorInfo cellStateInfo({numBatches , outputSize},
+                                    armnn::DataType::QSymmS16,
+                                    cellStateScale,
+                                    cellStateOffset);
+
+    armnn::TensorInfo outputStateInfo({numBatches , outputSize},
+                                      armnn::DataType::QAsymmU8,
+                                      inputOutputScale,
+                                      inputOutputOffset);
+
+    // Connect input/output slots
+    Connect(input, layer, inputInfo, 0, 0);
+    Connect(cellStateIn, layer, cellStateInfo, 0, 1);
+    Connect(outputStateIn, layer, outputStateInfo, 0, 2);
+
+    Connect(layer, cellStateOut, cellStateInfo, 0, 0);
+    Connect(layer, outputStateOut, outputStateInfo, 1, 0);
+
+    CreateTensorHandles(graph, factory);
+
+    // Create workload and check layer support
+    auto workload = MakeAndCheckWorkload<QuantizedLstmWorkload>(*layer, factory);
+    QuantizedLstmQueueDescriptor queueDescriptor = workload->GetData();
+
+    // Validate input/output sizes
+    CHECK(queueDescriptor.m_Inputs.size() == 3);
+    CHECK(queueDescriptor.m_Outputs.size() == 2);
+
+    // Validate weight tensor info
+    CHECK((queueDescriptor.m_InputToInputWeights->GetTensorInfo() == inputWeightsInfo));
+    CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == inputWeightsInfo));
+    CHECK((queueDescriptor.m_InputToCellWeights->GetTensorInfo() == inputWeightsInfo));
+    CHECK((queueDescriptor.m_InputToOutputWeights->GetTensorInfo() == inputWeightsInfo));
+
+    CHECK((queueDescriptor.m_RecurrentToInputWeights->GetTensorInfo() == recurrentWeightsInfo));
+    CHECK((queueDescriptor.m_RecurrentToForgetWeights->GetTensorInfo() == recurrentWeightsInfo));
+    CHECK((queueDescriptor.m_RecurrentToCellWeights->GetTensorInfo() == recurrentWeightsInfo));
+    CHECK((queueDescriptor.m_RecurrentToOutputWeights->GetTensorInfo() == recurrentWeightsInfo));
+
+    CHECK((queueDescriptor.m_InputGateBias->GetTensorInfo() == biasInfo));
+    CHECK((queueDescriptor.m_ForgetGateBias->GetTensorInfo() == biasInfo));
+    CHECK((queueDescriptor.m_CellBias->GetTensorInfo() == biasInfo));
+    CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() == biasInfo));
+
+    return workload;
+}
+
+template <typename QLstmWorkload>
+std::unique_ptr<QLstmWorkload> CreateQLstmWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                       armnn::Graph& graph)
+{
+    QLstmDescriptor layerDesc;
+    layerDesc.m_CifgEnabled       = true;
+    layerDesc.m_PeepholeEnabled   = false;
+    layerDesc.m_ProjectionEnabled = false;
+    layerDesc.m_LayerNormEnabled  = true;
+
+    layerDesc.m_CellClip       = 0.0f;
+    layerDesc.m_ProjectionClip = 0.0f;
+
+    layerDesc.m_HiddenStateZeroPoint = 0;
+    layerDesc.m_HiddenStateScale     = 0.007f;
+
+    layerDesc.m_InputIntermediateScale  = 0.007059f;
+    layerDesc.m_ForgetIntermediateScale = 0.007812f;
+    layerDesc.m_CellIntermediateScale   = 0.007059f;
+    layerDesc.m_OutputIntermediateScale = 0.007812f;
+
+    QLstmLayer* const layer = graph.AddLayer<QLstmLayer>(layerDesc, "qLstm");
+
+    unsigned int numBatches = 2;
+    unsigned int inputSize  = 4;
+    unsigned int numUnits   = 4;
+    unsigned int outputSize = 4;
+
+    // Scale/Offset quantization info
+    float inputScale    = 0.0078125f;
+    int32_t inputOffset = 0;
+
+    // if (!projectionEnabled) outputScale == hiddenStateScale
+    float outputScale    = layerDesc.m_HiddenStateScale;
+    int32_t outputOffset = layerDesc.m_HiddenStateZeroPoint;
+
+    float cellStateScale    = 3.05176e-05f;
+    int32_t cellStateOffset = 0;
+
+    float weightsScale    = 0.00784314f;
+    int32_t weightsOffset = 0;
+
+    float layerNormScale    = 3.05182e-05f;
+    int32_t layerNormOffset = 0;
+
+    float biasScale    = layerNormScale / 1024;
+    int32_t biasOffset = 0;
+
+    // Weights and bias tensor and quantization info
+    armnn::TensorInfo inputWeightsInfo({outputSize, inputSize},
+                                       armnn::DataType::QSymmS8,
+                                       weightsScale,
+                                       weightsOffset);
+
+    armnn::TensorInfo recurrentWeightsInfo({outputSize, outputSize},
+                                           armnn::DataType::QSymmS8,
+                                           weightsScale,
+                                           weightsOffset);
+
+    armnn::TensorInfo biasInfo({outputSize}, armnn::DataType::Signed32, biasScale, biasOffset);
+
+    armnn::TensorInfo layerNormWeightsInfo({numUnits}, armnn::DataType::QSymmS16, layerNormScale, layerNormOffset);
+
+    // Create and allocate tensors
+    layer->m_BasicParameters.m_InputToForgetWeights = std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
+    layer->m_BasicParameters.m_InputToCellWeights = std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
+    layer->m_BasicParameters.m_InputToOutputWeights = std::make_unique<ScopedTensorHandle>(inputWeightsInfo);
+
+    layer->m_BasicParameters.m_RecurrentToForgetWeights =
+            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
+    layer->m_BasicParameters.m_RecurrentToCellWeights =
+            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
+    layer->m_BasicParameters.m_RecurrentToOutputWeights =
+            std::make_unique<ScopedTensorHandle>(recurrentWeightsInfo);
+
+    layer->m_BasicParameters.m_ForgetGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
+    layer->m_BasicParameters.m_CellBias = std::make_unique<ScopedTensorHandle>(biasInfo);
+    layer->m_BasicParameters.m_OutputGateBias = std::make_unique<ScopedTensorHandle>(biasInfo);
+
+    layer->m_LayerNormParameters.m_ForgetLayerNormWeights =
+            std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
+    layer->m_LayerNormParameters.m_CellLayerNormWeights =
+            std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
+    layer->m_LayerNormParameters.m_OutputLayerNormWeights =
+            std::make_unique<ScopedTensorHandle>(layerNormWeightsInfo);
+
+    layer->m_BasicParameters.m_InputToForgetWeights->Allocate();
+    layer->m_BasicParameters.m_InputToCellWeights->Allocate();
+    layer->m_BasicParameters.m_InputToOutputWeights->Allocate();
+
+    layer->m_BasicParameters.m_RecurrentToForgetWeights->Allocate();
+    layer->m_BasicParameters.m_RecurrentToCellWeights->Allocate();
+    layer->m_BasicParameters.m_RecurrentToOutputWeights->Allocate();
+
+    layer->m_BasicParameters.m_ForgetGateBias->Allocate();
+    layer->m_BasicParameters.m_CellBias->Allocate();
+    layer->m_BasicParameters.m_OutputGateBias->Allocate();
+
+    layer->m_LayerNormParameters.m_ForgetLayerNormWeights->Allocate();
+    layer->m_LayerNormParameters.m_CellLayerNormWeights->Allocate();
+    layer->m_LayerNormParameters.m_OutputLayerNormWeights->Allocate();
+
+    // Input and output layers
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const outputStateIn = graph.AddLayer<InputLayer>(1, "outputStateIn");
+    Layer* const cellStateIn = graph.AddLayer<InputLayer>(2, "cellStateIn");
+
+    Layer* const outputStateOut = graph.AddLayer<OutputLayer>(0, "outputStateOut");
+    Layer* const cellStateOut = graph.AddLayer<OutputLayer>(1, "cellStateOut");
+    Layer* const output = graph.AddLayer<OutputLayer>(2, "output");
+
+    // Input/Output tensor info
+    armnn::TensorInfo inputInfo({numBatches , inputSize},
+                                armnn::DataType::QAsymmS8,
+                                inputScale,
+                                inputOffset);
+
+    armnn::TensorInfo cellStateInfo({numBatches , numUnits},
+                                    armnn::DataType::QSymmS16,
+                                    cellStateScale,
+                                    cellStateOffset);
+
+    armnn::TensorInfo outputStateInfo({numBatches , outputSize},
+                                      armnn::DataType::QAsymmS8,
+                                      outputScale,
+                                      outputOffset);
+
+    // Connect layers to slots
+    Connect(input, layer, inputInfo, 0, 0);
+    Connect(outputStateIn, layer, outputStateInfo, 0, 1);
+    Connect(cellStateIn, layer, cellStateInfo, 0, 2);
+
+    Connect(layer, outputStateOut, outputStateInfo, 0, 0);
+    Connect(layer, cellStateOut, cellStateInfo, 1, 0);
+    Connect(layer, output, outputStateInfo, 2, 0);
+
+    CreateTensorHandles(graph, factory);
+
+    // Create and check workload
+    auto workload = MakeAndCheckWorkload<QLstmWorkload>(*layer, factory);
+    QLstmQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_CellClip == 0.0f);
+    CHECK(queueDescriptor.m_Parameters.m_ProjectionClip == 0.0f);
+    CHECK(queueDescriptor.m_Inputs.size() == 3);
+    CHECK(queueDescriptor.m_Outputs.size() == 3);
+
+    CHECK((queueDescriptor.m_InputToForgetWeights->GetTensorInfo() == inputWeightsInfo));
+    CHECK((queueDescriptor.m_InputToCellWeights->GetTensorInfo() == inputWeightsInfo));
+    CHECK((queueDescriptor.m_InputToOutputWeights->GetTensorInfo() == inputWeightsInfo));
+
+    CHECK((queueDescriptor.m_RecurrentToForgetWeights->GetTensorInfo() == recurrentWeightsInfo));
+    CHECK((queueDescriptor.m_RecurrentToCellWeights->GetTensorInfo() == recurrentWeightsInfo));
+    CHECK((queueDescriptor.m_RecurrentToOutputWeights->GetTensorInfo() == recurrentWeightsInfo));
+
+    CHECK((queueDescriptor.m_ForgetGateBias->GetTensorInfo() == biasInfo));
+    CHECK((queueDescriptor.m_CellBias->GetTensorInfo() == biasInfo));
+    CHECK((queueDescriptor.m_OutputGateBias->GetTensorInfo() == biasInfo));
+
+    return workload;
+}
+
+template <typename Convolution2dWorkload, armnn::DataType DataType>
+std::unique_ptr<Convolution2dWorkload> CreateDirectConvolution2dWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                       armnn::Graph&            graph)
+{
+    // Creates the layer we're testing.
+    Convolution2dDescriptor layerDesc;
+    layerDesc.m_PadLeft = 1;
+    layerDesc.m_PadRight = 1;
+    layerDesc.m_PadTop = 1;
+    layerDesc.m_PadBottom = 1;
+    layerDesc.m_StrideX = 1;
+    layerDesc.m_StrideY = 1;
+    layerDesc.m_BiasEnabled = true;
+
+    Convolution2dLayer* const layer = graph.AddLayer<Convolution2dLayer>(layerDesc, "layer");
+
+    float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
+    float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
+
+    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo({ 2, 3, 3, 3 }, DataType, inputsQScale));
+    layer->m_Bias   = std::make_unique<ScopedTensorHandle>
+        (TensorInfo({2},  GetBiasDataType(DataType), inputsQScale));
+    layer->m_Weight->Allocate();
+    layer->m_Bias->Allocate();
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    Connect(input, layer, TensorInfo({2, 3, 6, 6}, DataType, inputsQScale));
+    Connect(layer, output, TensorInfo({2, 2, 6, 6}, DataType, outputQScale));
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<Convolution2dWorkload>(*layer, factory);
+
+    Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
+    CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadRight == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
+    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == true);
+
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo({2, 3, 3, 3},
+        DataType, inputsQScale)));
+    CHECK((queueDescriptor.m_Bias->GetTensorInfo()
+                == TensorInfo({2},  GetBiasDataType(DataType), inputsQScale)));
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename DepthwiseConvolution2dFloat32Workload, armnn::DataType DataType>
+std::unique_ptr<DepthwiseConvolution2dFloat32Workload> CreateDepthwiseConvolution2dWorkloadTest(
+    armnn::IWorkloadFactory& factory, armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW)
+{
+    // Creates the layer we're testing.
+    DepthwiseConvolution2dDescriptor layerDesc;
+    layerDesc.m_PadLeft     = 1;
+    layerDesc.m_PadRight    = 2;
+    layerDesc.m_PadTop      = 1;
+    layerDesc.m_PadBottom   = 2;
+    layerDesc.m_StrideX     = 1;
+    layerDesc.m_StrideY     = 1;
+    layerDesc.m_BiasEnabled = false;
+    layerDesc.m_DataLayout  = dataLayout;
+
+    DepthwiseConvolution2dLayer* const layer = graph.AddLayer<DepthwiseConvolution2dLayer>(layerDesc, "layer");
+
+    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo({1, 4, 4, 2}, DataType)); // [ 1, H, W, I*M ]
+    layer->m_Weight->Allocate();
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
+                TensorShape{ 2, 2, 5, 5 } : TensorShape{ 2, 5, 5, 2 };
+    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
+                TensorShape{ 2, 2, 5, 5 } : TensorShape{ 2, 5, 5, 2 };
+
+    // Connects up.
+    Connect(input, layer, TensorInfo(inputShape, DataType));
+    Connect(layer, output, TensorInfo(outputShape, DataType));
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<DepthwiseConvolution2dFloat32Workload>(*layer, factory);
+
+    DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_StrideX == 1);
+    CHECK(queueDescriptor.m_Parameters.m_StrideY == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadRight == 2);
+    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 2);
+    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == false);
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK((queueDescriptor.m_Weight->GetTensorInfo() == TensorInfo({1, 4, 4, 2}, DataType)));
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename FullyConnectedWorkload, armnn::DataType DataType>
+std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                         armnn::Graph&            graph)
+{
+    // Creates the layer we're testing.
+    FullyConnectedDescriptor layerDesc;
+    layerDesc.m_BiasEnabled = false;
+    layerDesc.m_TransposeWeightMatrix = true;
+
+    FullyConnectedLayer* const layer = graph.AddLayer<FullyConnectedLayer>(layerDesc, "layer");
+
+    float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
+    float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
+
+    // As optimization isn't run member variables need to be updated.
+    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo({7, 20}, DataType, inputsQScale, 0));
+    layer->m_Weight->Allocate();
+
+    armnn::TensorInfo weightsTensorInfo({7, 20}, DataType, inputsQScale);
+    weightsTensorInfo.SetConstant();
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    auto const weights = graph.AddLayer<ConstantLayer>("weights");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    weights->m_LayerOutput = std::make_unique<ScopedTensorHandle>(weightsTensorInfo);
+    weights->m_LayerOutput->Allocate();
+
+    // Connects up.
+    Connect(input, layer, TensorInfo({3, 1, 4, 5}, DataType, inputsQScale), 0, 0);
+    Connect(weights, layer, weightsTensorInfo, 0, 1);
+    Connect(layer, output, TensorInfo({3, 7}, DataType, outputQScale));
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
+
+    FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix == true);
+
+    CHECK(queueDescriptor.m_Inputs.size() == 2);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename FullyConnectedWorkload, armnn::DataType DataType>
+std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWithBlobWorkloadTest
+    (armnn::IWorkloadFactory& factory,
+     armnn::Graph& graph)
+{
+    // Creates the layer we're testing.
+    FullyConnectedDescriptor layerDesc;
+    layerDesc.m_BiasEnabled = true;
+    layerDesc.m_TransposeWeightMatrix = true;
+
+    FullyConnectedLayer* const layer = graph.AddLayer<FullyConnectedLayer>(layerDesc, "layer");
+
+    float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
+    float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
+
+    // As optimization isn't run member variables need to be updated.
+    layer->m_Weight = std::make_unique<ScopedTensorHandle>(TensorInfo({7, 20}, DataType, inputsQScale, 0));
+    layer->m_Bias   = std::make_unique<ScopedTensorHandle>(TensorInfo({7}, GetBiasDataType(DataType), inputsQScale));
+    layer->m_Weight->Allocate();
+    layer->m_Bias->Allocate();
+
+    armnn::TensorInfo weightsTensorInfo({7, 20}, DataType, inputsQScale);
+    armnn::TensorInfo biasesTensorInfo({7}, GetBiasDataType(DataType), inputsQScale);
+    weightsTensorInfo.SetConstant();
+    biasesTensorInfo.SetConstant();
+
+    auto activationDesc = std::make_shared<ActivationDescriptor>();
+    activationDesc->m_A        = 10.0f;
+    activationDesc->m_B        = 5.0f;
+    activationDesc->m_Function = armnn::ActivationFunction::BoundedReLu;
+
+    layer->SetAdditionalInfoForObject(activationDesc);
+
+    // Check that the additional information can be queried from the layer
+    std::shared_ptr<ActivationDescriptor> activationDescPtr = layer->GetAdditionalInformation<ActivationDescriptor>();
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(activationDescPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(static_cast<ActivationFunction>(activationDescPtr->m_Function) ==
+        armnn::ActivationFunction::BoundedReLu);
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    auto const weights = graph.AddLayer<ConstantLayer>("weights");
+    auto const biases = graph.AddLayer<ConstantLayer>("biases");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    weights->m_LayerOutput = std::make_unique<ScopedTensorHandle>(weightsTensorInfo);
+    weights->m_LayerOutput->Allocate();
+    biases->m_LayerOutput = std::make_unique<ScopedTensorHandle>(biasesTensorInfo);
+    biases->m_LayerOutput->Allocate();
+
+    // Connects up.
+    Connect(input, layer, TensorInfo({3, 1, 4, 5}, DataType, inputsQScale), 0, 0);
+    Connect(weights, layer, weightsTensorInfo, 0, 1);
+    Connect(biases, layer, biasesTensorInfo, 0, 2);
+    Connect(layer, output, TensorInfo({3, 7}, DataType, outputQScale));
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
+
+    FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
+
+    const ActivationDescriptor* queueDescBlobPtr = queueDescriptor.GetAdditionalInformation<ActivationDescriptor>();
+    IgnoreUnused(queueDescBlobPtr);
+
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_A) == 10.0f);
+    ARMNN_ASSERT(static_cast<float>(queueDescBlobPtr->m_B) == 5.0f);
+    ARMNN_ASSERT(
+        static_cast<ActivationFunction>(queueDescBlobPtr->m_Function) == armnn::ActivationFunction::BoundedReLu
+    );
+
+    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == true);
+    CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix == true);
+    CHECK(queueDescriptor.m_Inputs.size() == 3);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename FullyConnectedWorkload, armnn::DataType DataType>
+std::unique_ptr<FullyConnectedWorkload> CreateFullyConnectedWorkloadWeightsBiasesAsInputsTest
+    (armnn::IWorkloadFactory& factory,
+     armnn::Graph&            graph)
+{
+    // Creates the layer we're testing.
+    FullyConnectedDescriptor layerDesc;
+    layerDesc.m_BiasEnabled = true;
+    layerDesc.m_TransposeWeightMatrix = true;
+    layerDesc.m_ConstantWeights = false;
+
+    FullyConnectedLayer* const layer = graph.AddLayer<FullyConnectedLayer>(layerDesc, "layer");
+
+    float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
+    float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
+
+    // Creates extra layers with weights and biases as input layers.
+    Layer* const input   = graph.AddLayer<InputLayer>(1, "input");
+    Layer* const weights = graph.AddLayer<InputLayer>(2, "weights");
+    Layer* const biases  = graph.AddLayer<InputLayer>(3, "biases");
+    Layer* const output  = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    Connect(input, layer, TensorInfo({3, 1, 4, 5}, DataType, inputsQScale), 0, 0);
+    Connect(weights, layer, TensorInfo({7, 20}, DataType, inputsQScale), 0, 1);
+    Connect(biases, layer, TensorInfo({7}, GetBiasDataType(DataType), inputsQScale), 0, 2);
+    Connect(layer, output, TensorInfo({3, 7}, DataType, outputQScale));
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<FullyConnectedWorkload>(*layer, factory);
+
+    FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
+
+    CHECK(queueDescriptor.m_Parameters.m_BiasEnabled == true);
+    CHECK(queueDescriptor.m_Parameters.m_TransposeWeightMatrix == true);
+    CHECK(queueDescriptor.m_Parameters.m_ConstantWeights == false);
+    CHECK(queueDescriptor.m_Inputs.size() == 3);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+
+template <typename NormalizationWorkload, armnn::DataType DataType>
+std::unique_ptr<NormalizationWorkload> CreateNormalizationWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                       armnn::Graph& graph,
+                                                                       DataLayout dataLayout = DataLayout::NCHW)
+{
+    // Creates the layer we're testing.
+    NormalizationDescriptor layerDesc;
+    layerDesc.m_NormChannelType = NormalizationAlgorithmChannel::Across;
+    layerDesc.m_NormMethodType = NormalizationAlgorithmMethod::LocalBrightness;
+    layerDesc.m_NormSize = 3;
+    layerDesc.m_Alpha = 0.5f;
+    layerDesc.m_Beta = -1.0f;
+    layerDesc.m_K = 0.2f;
+    layerDesc.m_DataLayout = dataLayout;
+
+    NormalizationLayer* layer = graph.AddLayer<NormalizationLayer>(layerDesc, "layer");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
+                TensorShape{ 3, 5, 5, 1 } : TensorShape{ 3, 1, 5, 5 };
+    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
+                TensorShape{ 3, 5, 5, 1 } : TensorShape{ 3, 1, 5, 5 };
+
+    // Connects up.
+    armnn::TensorInfo inputTensorInfo(inputShape, DataType);
+    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
+    Connect(input, layer, inputTensorInfo);
+    Connect(layer, output, outputTensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<NormalizationWorkload>(*layer, factory);
+
+    NormalizationQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK((queueDescriptor.m_Parameters.m_NormChannelType == NormalizationAlgorithmChannel::Across));
+    CHECK((queueDescriptor.m_Parameters.m_NormMethodType == NormalizationAlgorithmMethod::LocalBrightness));
+    CHECK(queueDescriptor.m_Parameters.m_NormSize == 3);
+    CHECK(queueDescriptor.m_Parameters.m_Alpha == 0.5f);
+    CHECK(queueDescriptor.m_Parameters.m_Beta == -1.0f);
+    CHECK(queueDescriptor.m_Parameters.m_K == 0.2f);
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename Pooling2dWorkload, armnn::DataType DataType>
+std::unique_ptr<Pooling2dWorkload> CreatePooling2dWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                               armnn::Graph&            graph,
+                                                               DataLayout dataLayout = DataLayout::NCHW)
+{
+    // Creates the layer we're testing.
+    Pooling2dDescriptor layerDesc;
+    layerDesc.m_PoolType = PoolingAlgorithm::Average;
+    layerDesc.m_PoolWidth = 3;
+    layerDesc.m_PoolHeight = 3;
+    layerDesc.m_PadLeft = 2;
+    layerDesc.m_PadRight = 2;
+    layerDesc.m_PadTop = 1;
+    layerDesc.m_PadBottom = 1;
+    layerDesc.m_StrideX = 2;
+    layerDesc.m_StrideY = 3;
+    layerDesc.m_OutputShapeRounding = OutputShapeRounding::Floor;
+    layerDesc.m_DataLayout = dataLayout;
+
+    Pooling2dLayer* const layer = graph.AddLayer<Pooling2dLayer>(layerDesc, "layer");
+
+    // Create extra layers
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
+    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
+
+    // Connect up
+    Connect(input, layer, TensorInfo(inputShape, DataType));
+    Connect(layer, output, TensorInfo(outputShape, DataType));
+    CreateTensorHandles(graph, factory);
+
+    // Make the workload and checks it
+    auto workload = MakeAndCheckWorkload<Pooling2dWorkload>(*layer, factory);
+
+    Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK((queueDescriptor.m_Parameters.m_PoolType == PoolingAlgorithm::Average));
+    CHECK((queueDescriptor.m_Parameters.m_OutputShapeRounding == OutputShapeRounding::Floor));
+    CHECK(queueDescriptor.m_Parameters.m_PoolWidth == 3);
+    CHECK(queueDescriptor.m_Parameters.m_PoolHeight == 3);
+    CHECK(queueDescriptor.m_Parameters.m_StrideX == 2);
+    CHECK(queueDescriptor.m_Parameters.m_StrideY == 3);
+    CHECK(queueDescriptor.m_Parameters.m_PadLeft == 2);
+    CHECK(queueDescriptor.m_Parameters.m_PadRight == 2);
+    CHECK(queueDescriptor.m_Parameters.m_PadTop == 1);
+    CHECK(queueDescriptor.m_Parameters.m_PadBottom == 1);
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Return so we can do extra, backend-specific tests
+    return workload;
+}
+
+template <typename SoftmaxWorkload, armnn::DataType DataType>
+std::unique_ptr<SoftmaxWorkload> CreateSoftmaxWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                           armnn::Graph&            graph)
+{
+    // Create the layer we're testing.
+    SoftmaxDescriptor softmaxDescriptor;
+    // Set Axis to -1 if CL or Neon until further Axes are supported.
+    if (factory.GetBackendId() == armnn::Compute::CpuAcc || factory.GetBackendId() == armnn::Compute::GpuAcc)
+    {
+        softmaxDescriptor.m_Axis = -1;
+    }
+
+    Layer* const layer = graph.AddLayer<SoftmaxLayer>(softmaxDescriptor, "layer");
+    // Create extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connect up
+    armnn::TensorInfo tensorInfo({4, 1}, DataType);
+    if (DataType == armnn::DataType::QAsymmU8)
+    {
+        tensorInfo.SetQuantizationOffset(0);
+        tensorInfo.SetQuantizationScale(1.f / 256);
+    }
+    else if (DataType == armnn::DataType::QAsymmS8)
+    {
+        tensorInfo.SetQuantizationOffset(-128);
+        tensorInfo.SetQuantizationScale(1.f / 256);
+    }
+
+    Connect(input, layer, tensorInfo);
+    Connect(layer, output, tensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Make the workload and checks it.
+    auto workload = MakeAndCheckWorkload<SoftmaxWorkload>(*layer, factory);
+
+    SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Return so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template<typename SplitterWorkload, armnn::DataType DataType>
+std::unique_ptr<SplitterWorkload>
+    CreateSplitterWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph)
+{
+    // Create the layer we're testing.
+    // NOTE: need three dimensions channels, height/y, width/x because the Compute
+    //       library restricts subtensors to have the same x and y dimensions as
+    //       their parent tensors, and therefore the origin on the x and y dimension
+    //       has to be zero for any view. So we need a third dimension to split...
+    // NOTE: arguments are: number of views, number of dimensions.
+    ViewsDescriptor layerDesc(3, 3);
+    // NOTE: arguments are: view, dimension, value.
+    layerDesc.SetViewOriginCoord(0, 0, 0);
+    layerDesc.SetViewOriginCoord(1, 0, 1);
+    layerDesc.SetViewOriginCoord(2, 0, 3);
+
+    Layer* const layer = graph.AddLayer<SplitterLayer>(layerDesc, "layer");
+
+    // Adds extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output0 = graph.AddLayer<OutputLayer>(0, "output0");
+    Layer* const output1 = graph.AddLayer<OutputLayer>(1, "output1");
+    Layer* const output2 = graph.AddLayer<OutputLayer>(2, "output2");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo({5, 7, 7}, DataType);
+    Connect(input, layer, tensorInfo);
+
+    armnn::TensorInfo output0Info({1, 7, 7}, DataType);
+    armnn::TensorInfo output1Info({2, 7, 7}, DataType);
+    armnn::TensorInfo output2Info({2, 7, 7}, DataType);
+
+    Connect(layer, output0, output0Info, 0, 0);
+    Connect(layer, output1, output1Info, 1, 0);
+    Connect(layer, output2, output2Info, 2, 0);
+
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<SplitterWorkload>(*layer, factory);
+
+    SplitterQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 3);
+    CHECK(queueDescriptor.m_ViewOrigins.size() == 3);
+
+    CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[0] == 0);
+    CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[0] == 1);
+    CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[0] == 3);
+    CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[1] == 0);
+    CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[1] == 0);
+    CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[1] == 0);
+    CHECK(queueDescriptor.m_ViewOrigins[0].m_Origin[2] == 0);
+    CHECK(queueDescriptor.m_ViewOrigins[1].m_Origin[2] == 0);
+    CHECK(queueDescriptor.m_ViewOrigins[2].m_Origin[2] == 0);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+/// This function constructs a graph with both a splitter and a concat, and returns a pair of the workloads.
+template<typename SplitterWorkload, typename ConcatWorkload, armnn::DataType DataType>
+std::pair<std::unique_ptr<SplitterWorkload>, std::unique_ptr<ConcatWorkload>>
+    CreateSplitterConcatWorkloadTest(armnn::IWorkloadFactory &factory, armnn::Graph &graph)
+{
+    armnn::TensorInfo inputTensorInfo({ 1, 2, 100, 10 }, DataType);
+
+    armnn::TensorInfo splitTensorInfo1({ 1, 1, 100, 10 }, DataType);
+    armnn::TensorInfo splitTensorInfo2({ 1, 1, 100, 10 }, DataType);
+
+    //Constructs the graph.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+
+    armnn::ViewsDescriptor splitterViews(2);
+    splitterViews.SetViewOriginCoord(0, 0, 0);
+    splitterViews.SetViewOriginCoord(0, 1, 0);
+    splitterViews.SetViewOriginCoord(0, 2, 0);
+    splitterViews.SetViewOriginCoord(0, 3, 0);
+
+    splitterViews.SetViewOriginCoord(1, 0, 0);
+    splitterViews.SetViewOriginCoord(1, 1, 1);
+    splitterViews.SetViewOriginCoord(1, 2, 0);
+    splitterViews.SetViewOriginCoord(1, 3, 0);
+
+    // create splitter layer
+    Layer* const splitter = graph.AddLayer<SplitterLayer>(splitterViews, "splitter");
+    CHECK(splitter);
+
+    armnn::OriginsDescriptor concatViews(2);
+    concatViews.SetViewOriginCoord(0, 0, 0);
+    concatViews.SetViewOriginCoord(0, 1, 1);
+    concatViews.SetViewOriginCoord(0, 2, 0);
+    concatViews.SetViewOriginCoord(0, 3, 0);
+
+    concatViews.SetViewOriginCoord(1, 0, 0);
+    concatViews.SetViewOriginCoord(1, 1, 0);
+    concatViews.SetViewOriginCoord(1, 2, 0);
+    concatViews.SetViewOriginCoord(1, 3, 0);
+
+    // create concat layer
+    Layer* const concat = graph.AddLayer<ConcatLayer>(concatViews, "concat");
+    CHECK(concat);
+
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Adds connections.
+    // connect input to splitter
+    Connect(input, splitter, inputTensorInfo, 0, 0);
+    // connect splitter[0] to concat[1]
+    Connect(splitter, concat, splitTensorInfo1, 0, 1); // The splitter & concat are connected up.
+    // connect splitter[1] to concat[0]
+    Connect(splitter, concat, splitTensorInfo2, 1, 0); // So that the outputs are flipped round.
+    // connect concat to output
+    Connect(concat, output, inputTensorInfo, 0, 0);
+
+    // created tensor handles
+    CreateTensorHandles(graph, factory);
+
+    // created splitter workload
+    auto workloadSplitter = MakeAndCheckWorkload<SplitterWorkload>(*splitter, factory);
+    CHECK(workloadSplitter);
+    // created concat workload
+    auto workloadConcat = MakeAndCheckWorkload<ConcatWorkload>(*concat, factory);
+    CHECK(workloadConcat);
+
+    return {std::move(workloadSplitter), std::move(workloadConcat)};
+}
+
+
+/// This function constructs a graph with a splitter with two outputs. Each of the outputs is then
+/// connected to two different activation layers
+template<typename SplitterWorkload, typename ActivationWorkload, armnn::DataType DataType>
+void CreateSplitterMultipleInputsOneOutputWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph,
+                                 std::unique_ptr<SplitterWorkload>& wlSplitter,
+                                 std::unique_ptr<ActivationWorkload>& wlActiv0_0,
+                                 std::unique_ptr<ActivationWorkload>& wlActiv0_1,
+                                 std::unique_ptr<ActivationWorkload>& wlActiv1_0,
+                                 std::unique_ptr<ActivationWorkload>& wlActiv1_1)
+{
+    armnn::TensorInfo inputTensorInfo ({ 1, 3, 100, 50 }, DataType);
+    armnn::TensorInfo splitTensorInfo1({ 1, 1, 100, 50 }, DataType);
+    armnn::TensorInfo splitTensorInfo2({ 1, 2, 100, 50 }, DataType);
+
+    //Constructs the graph.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+
+    armnn::ViewsDescriptor splitterViews(2);
+
+    splitterViews.SetViewOriginCoord(0, 0, 0);
+    splitterViews.SetViewOriginCoord(0, 1, 0);
+    splitterViews.SetViewOriginCoord(0, 2, 0);
+    splitterViews.SetViewOriginCoord(0, 3, 0);
+
+    splitterViews.SetViewOriginCoord(1, 0, 0);
+    splitterViews.SetViewOriginCoord(1, 1, 1);
+    splitterViews.SetViewOriginCoord(1, 2, 0);
+    splitterViews.SetViewOriginCoord(1, 3, 0);
+
+    Layer* const splitter = graph.AddLayer<SplitterLayer>(splitterViews, "splitter");
+
+    armnn::ActivationDescriptor activationDesc;
+
+    Layer* const activ0_0 = graph.AddLayer<ActivationLayer>(activationDesc, "activ0_0");
+    Layer* const activ0_1 = graph.AddLayer<ActivationLayer>(activationDesc, "activ0_1");
+    Layer* const activ1_0 = graph.AddLayer<ActivationLayer>(activationDesc, "activ1_0");
+    Layer* const activ1_1 = graph.AddLayer<ActivationLayer>(activationDesc, "activ1_1");
+
+    Layer* const output1 = graph.AddLayer<OutputLayer>(1, "output1");
+    Layer* const output2 = graph.AddLayer<OutputLayer>(2, "output2");
+    Layer* const output3 = graph.AddLayer<OutputLayer>(3, "output3");
+    Layer* const output4 = graph.AddLayer<OutputLayer>(4, "output4");
+
+    // Adds connections.
+    Connect(input, splitter, inputTensorInfo, 0, 0);
+    Connect(splitter, activ0_0, splitTensorInfo1, 0, 0);
+    Connect(splitter, activ0_1, splitTensorInfo1, 0, 0);
+
+    Connect(splitter, activ1_0, splitTensorInfo2, 1, 0);
+    Connect(splitter, activ1_1, splitTensorInfo2, 1, 0);
+
+    Connect(activ0_0, output1, splitTensorInfo1, 0, 0);
+    Connect(activ0_1, output2, splitTensorInfo1, 0, 0);
+    Connect(activ1_0, output3, splitTensorInfo2, 0, 0);
+    Connect(activ1_1, output4, splitTensorInfo2, 0, 0);
+
+    CreateTensorHandles(graph, factory);
+
+    auto workloadSplitter = MakeAndCheckWorkload<SplitterWorkload>(*splitter, factory);
+    auto workloadActiv0_0 = MakeAndCheckWorkload<ActivationWorkload>(*activ0_0, factory);
+    auto workloadActiv0_1 = MakeAndCheckWorkload<ActivationWorkload>(*activ0_1, factory);
+    auto workloadActiv1_0 = MakeAndCheckWorkload<ActivationWorkload>(*activ1_0, factory);
+    auto workloadActiv1_1 = MakeAndCheckWorkload<ActivationWorkload>(*activ1_1, factory);
+
+    wlSplitter = std::move(workloadSplitter);
+    wlActiv0_0 = std::move(workloadActiv0_0);
+    wlActiv0_1 = std::move(workloadActiv0_1);
+    wlActiv1_0 = std::move(workloadActiv1_0);
+    wlActiv1_1 = std::move(workloadActiv1_1);
+}
+
+template <typename ResizeWorkload, armnn::DataType DataType>
+std::unique_ptr<ResizeWorkload> CreateResizeBilinearWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                 armnn::Graph& graph,
+                                                                 DataLayout dataLayout = DataLayout::NCHW)
+{
+    TensorShape inputShape;
+    TensorShape outputShape;
+
+    switch (dataLayout) {
+        case DataLayout::NHWC:
+            inputShape =  { 2, 4, 4, 3 };
+            outputShape = { 2, 2, 2, 3 };
+            break;
+        case DataLayout::NCHW:
+        default:
+            inputShape =  { 2, 3, 4, 4 };
+            outputShape = { 2, 3, 2, 2 };
+    }
+
+    // Creates the layer we're testing.
+    ResizeDescriptor resizeDesc;
+    armnnUtils::DataLayoutIndexed dimensionIndices = dataLayout;
+    resizeDesc.m_Method       = ResizeMethod::Bilinear;
+    resizeDesc.m_TargetWidth  = outputShape[dimensionIndices.GetWidthIndex()];
+    resizeDesc.m_TargetHeight = outputShape[dimensionIndices.GetHeightIndex()];
+    resizeDesc.m_DataLayout   = dataLayout;
+    Layer* const layer = graph.AddLayer<ResizeLayer>(resizeDesc, "resize");
+
+    // Creates extra layers.
+    Layer* const input  = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo inputTensorInfo(inputShape, DataType);
+    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
+    Connect(input, layer, inputTensorInfo);
+    Connect(layer, output, outputTensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<ResizeWorkload>(*layer, factory);
+
+    auto queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size()  == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+    CHECK(queueDescriptor.m_Parameters.m_DataLayout == dataLayout);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename BatchToSpaceNdWorkload, armnn::DataType DataType>
+std::unique_ptr<BatchToSpaceNdWorkload> CreateBatchToSpaceNdWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                         armnn::Graph&  graph)
+{
+    BatchToSpaceNdDescriptor desc;
+    Layer* const layer = graph.AddLayer<BatchToSpaceNdLayer>(desc, "batchToSpace");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo tensorInfo({1, 1, 1, 1}, DataType);
+
+    Connect(input, layer, tensorInfo);
+    Connect(layer, output, tensorInfo);
+
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<BatchToSpaceNdWorkload>(*layer, factory);
+
+    BatchToSpaceNdQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    return workload;
+}
+
+template <typename LogSoftmaxWorkload, armnn::DataType DataType>
+std::unique_ptr<LogSoftmaxWorkload> CreateLogSoftmaxWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                 armnn::Graph& graph)
+{
+    // Create the layer we're testing.
+    LogSoftmaxDescriptor logSoftmaxDescriptor;
+    // Set Axis to -1 if CL or Neon until further Axes are supported.
+    if (factory.GetBackendId() == armnn::Compute::CpuAcc || factory.GetBackendId() == armnn::Compute::GpuAcc)
+    {
+        logSoftmaxDescriptor.m_Axis = -1;
+    }
+
+    Layer* const layer = graph.AddLayer<LogSoftmaxLayer>(logSoftmaxDescriptor, "layer");
+    // Create extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connect up
+    armnn::TensorInfo tensorInfo({4, 1}, DataType);
+
+    Connect(input, layer, tensorInfo);
+    Connect(layer, output, tensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Make the workload and checks it.
+    auto workload = MakeAndCheckWorkload<LogSoftmaxWorkload>(*layer, factory);
+
+    LogSoftmaxQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Return so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename L2NormalizationWorkload, armnn::DataType DataType>
+std::unique_ptr<L2NormalizationWorkload> CreateL2NormalizationWorkloadTest(armnn::IWorkloadFactory& factory,
+    armnn::Graph& graph, DataLayout dataLayout = DataLayout::NCHW)
+{
+    // Creates the layer we're testing.
+    L2NormalizationDescriptor layerDesc;
+    layerDesc.m_DataLayout = dataLayout;
+
+    Layer* const layer = graph.AddLayer<L2NormalizationLayer>(layerDesc, "l2norm");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
+                TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
+    TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
+                TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
+
+    // Connects up.
+    armnn::TensorInfo inputTensorInfo(inputShape, DataType);
+    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
+    Connect(input, layer, inputTensorInfo);
+    Connect(layer, output, outputTensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<L2NormalizationWorkload>(*layer, factory);
+
+    L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK((queueDescriptor.m_Parameters.m_DataLayout == dataLayout));
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename ReshapeWorkload, armnn::DataType DataType>
+std::unique_ptr<ReshapeWorkload> CreateReshapeWorkloadTest(armnn::IWorkloadFactory& factory,
+    armnn::Graph& graph)
+{
+    // Creates the layer we're testing.
+    TensorShape outputShape({ 1, 4 });
+    ReshapeDescriptor reshapeDesc;
+    reshapeDesc.m_TargetShape = outputShape;
+    Layer* const layer = graph.AddLayer<ReshapeLayer>(reshapeDesc, "layer");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo inputTensorInfo({ 4, 1 }, DataType);
+    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
+    Connect(input, layer, inputTensorInfo);
+    Connect(layer, output, outputTensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<ReshapeWorkload>(*layer, factory);
+
+    ReshapeQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename ConvertFp16ToFp32Float32Workload>
+std::unique_ptr<ConvertFp16ToFp32Float32Workload> CreateConvertFp16ToFp32WorkloadTest(
+    armnn::IWorkloadFactory& factory, armnn::Graph& graph)
+{
+    // Creates the layer we're testing.
+    ConvertFp16ToFp32Layer* const layer = graph.AddLayer<ConvertFp16ToFp32Layer>("Fp16ToFp32Converter");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo inputTensorInfo({1, 3, 2, 3}, armnn::DataType::Float16);
+    armnn::TensorInfo outputTensorInfo({1, 3, 2, 3}, armnn::DataType::Float32);
+    Connect(input, layer, inputTensorInfo);
+    Connect(layer, output, outputTensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<ConvertFp16ToFp32Float32Workload>(*layer, factory);
+
+    ConvertFp16ToFp32QueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename ConvertFp32ToFp16Float16Workload>
+std::unique_ptr<ConvertFp32ToFp16Float16Workload> CreateConvertFp32ToFp16WorkloadTest(
+    armnn::IWorkloadFactory& factory, armnn::Graph& graph)
+{
+    // Creates the layer we're testing.
+    ConvertFp32ToFp16Layer* const layer = graph.AddLayer<ConvertFp32ToFp16Layer>("Fp32ToFp16Converter");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo inputTensorInfo({1, 3, 2, 3}, armnn::DataType::Float32);
+    armnn::TensorInfo outputTensorInfo({1, 3, 2, 3}, armnn::DataType::Float16);
+    Connect(input, layer, inputTensorInfo);
+    Connect(layer, output, outputTensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<ConvertFp32ToFp16Float16Workload>(*layer, factory);
+
+    ConvertFp32ToFp16QueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename MeanWorkload, armnn::DataType DataType>
+std::unique_ptr<MeanWorkload> CreateMeanWorkloadTest(armnn::IWorkloadFactory& factory, armnn::Graph& graph)
+{
+    // Reduce along the first and second dimensions, and do not keep the reduced dimensions.
+    MeanDescriptor descriptor({ 1, 2 }, false);
+
+    // Creates the layer we're testing.
+    Layer* const layer = graph.AddLayer<MeanLayer>(descriptor, "mean");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo inputTensorInfo({ 1, 3, 7, 4 }, DataType);
+    armnn::TensorInfo outputTensorInfo({ 1, 4 }, DataType);
+    Connect(input, layer, inputTensorInfo);
+    Connect(layer, output, outputTensorInfo);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<MeanWorkload>(*layer, factory);
+
+    MeanQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Parameters.m_Axis == descriptor.m_Axis);
+    CHECK(queueDescriptor.m_Parameters.m_KeepDims == descriptor.m_KeepDims);
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template<typename ConcatWorkload, armnn::DataType DataType>
+std::unique_ptr<ConcatWorkload> CreateConcatWorkloadTest(armnn::IWorkloadFactory &factory,
+                                                         armnn::Graph &graph,
+                                                         const armnn::TensorShape &outputShape,
+                                                         unsigned int concatAxis)
+{
+    armnn::TensorInfo inputTensorInfo({ 2, 3, 2, 5 }, DataType);
+    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
+
+    // Constructs the graph.
+    Layer* const input0 = graph.AddLayer<InputLayer>(0, "input0");
+    Layer* const input1 = graph.AddLayer<InputLayer>(1, "input1");
+    armnn::OriginsDescriptor descriptor;
+
+    std::vector<armnn::TensorShape> inputShapes{{ 2, 3, 2, 5 }, { 2, 3, 2, 5 }};
+
+    descriptor = CreateDescriptorForConcatenation(inputShapes.begin(),
+                                                  inputShapes.end(),
+                                                  concatAxis);
+
+    // create concat layer
+    Layer* const concat = graph.AddLayer<ConcatLayer>(descriptor, "concat");
+    CHECK(concat);
+
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Adds connections.
+    // connect input0 to concat
+    Connect(input0, concat, inputTensorInfo, 0, 0);
+    // connect input1 to concat
+    Connect(input1, concat, inputTensorInfo, 0, 1);
+    // connect concat to output
+    Connect(concat, output, outputTensorInfo, 0, 0);
+
+    // create tensor handles
+    CreateTensorHandles(graph, factory);
+
+    // create concat workload
+    auto workloadConcat = MakeAndCheckWorkload<ConcatWorkload>(*concat, factory);
+    CHECK(workloadConcat);
+
+    return workloadConcat;
+}
+
+template <typename PreCompiledWorkload, armnn::DataType dataType>
+std::pair<armnn::IOptimizedNetworkPtr, std::unique_ptr<PreCompiledWorkload>> CreatePreCompiledWorkloadTest(
+    armnn::IWorkloadFactory& factory,
+    armnn::Graph& graph,
+    bool biasEnabled = false)
+{
+    IgnoreUnused(graph);
+
+    // build up the structure of the network
+    armnn::INetworkPtr net(armnn::INetwork::Create());
+
+    // Add an input layer
+    armnn::IConnectableLayer* const inputLayer = net->AddInputLayer(0, "input layer");
+    CHECK(inputLayer);
+
+    // ArmNN weights tensor shape is OIHW (out channels, in channels, height, width) for NCHW
+    // ArmNN weights tensor shape is OHWI (out channels, height, width, in channels) for NHWC
+    // this test is using NHWC, so the weights shape is OHWI
+    TensorInfo weightsTensorInfo(TensorShape({16, 1, 1, 16}), dataType, 0.9f, 0, true);
+    unsigned int weightsLength = weightsTensorInfo.GetNumElements();
+
+    using WeightType = armnn::ResolveType<dataType>;
+    std::vector<WeightType> convWeightsData(weightsLength);
+    for (unsigned int i = 0; i < weightsLength; ++i)
+    {
+        convWeightsData[i] = static_cast<WeightType>(i);
+    }
+
+    armnn::ConstTensor weights(weightsTensorInfo, convWeightsData);
+
+    // Add a layer that can be used in the PreCompiled layer
+    armnn::Convolution2dDescriptor convDesc2d;
+    convDesc2d.m_StrideX = 1;
+    convDesc2d.m_StrideY = 1;
+    convDesc2d.m_BiasEnabled = biasEnabled;
+    convDesc2d.m_DataLayout = armnn::DataLayout::NHWC;
+
+    armnn::IConnectableLayer* convLayer = nullptr;
+    const std::string convLayerName("conv layer");
+
+    if (biasEnabled)
+    {
+        constexpr armnn::DataType biasDataType = ( dataType == armnn::DataType::QAsymmU8) ?
+            armnn::DataType::Signed32 : armnn::DataType::Float32;
+
+        TensorInfo biasTensorInfo(TensorShape({16}), biasDataType, 0.9f * 0.9f, 0, true);
+        unsigned int biasLength = biasTensorInfo.GetNumElements();
+
+        using BiasType = armnn::ResolveType<biasDataType>;
+        std::vector<BiasType> biasData(biasLength);
+        std::fill(biasData.begin(), biasData.end(), static_cast<BiasType>(0));
+
+        armnn::ConstTensor biases(biasTensorInfo, biasData);
+
+        // Create convolution layer with biases
+        convLayer = net->AddConvolution2dLayer(convDesc2d,
+                                              weights,
+                                              Optional<ConstTensor>(biases),
+                                              convLayerName.c_str());
+    }
+    else
+    {
+        // Create convolution layer without biases
+        convLayer = net->AddConvolution2dLayer(convDesc2d,
+                                              weights,
+                                              EmptyOptional(),
+                                              convLayerName.c_str());
+    }
+
+    CHECK(convLayer);
+
+    // Add an output layer
+    armnn::IConnectableLayer* const outputLayer = net->AddOutputLayer(0, "output layer");
+    CHECK(outputLayer);
+
+    // set the tensors in the network (NHWC format)
+    TensorInfo inputTensorInfo(TensorShape({ 1, 16, 16, 16 }), dataType);
+    if (dataType == armnn::DataType::QAsymmU8)
+    {
+        inputTensorInfo.SetQuantizationOffset(0);
+        inputTensorInfo.SetQuantizationScale(0.9f);
+    }
+
+    TensorInfo outputTensorInfo(TensorShape({1, 16, 16, 16}), dataType);
+    if (dataType == armnn::DataType::QAsymmU8)
+    {
+        outputTensorInfo.SetQuantizationOffset(0);
+        outputTensorInfo.SetQuantizationScale(0.9f);
+    }
+
+    // Connect the layers
+    inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
+    inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
+
+    convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
+    convLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
+
+    // Optimize the network for the backend supported by the factory
+    std::vector<armnn::BackendId> backends = {factory.GetBackendId()};
+    armnn::IRuntime::CreationOptions options;
+    armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
+    armnn::OptimizerOptions optimizerOptions;
+    armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec(),
+                                                               optimizerOptions);
+    CHECK(optimizedNet != nullptr);
+
+    // Find the PreCompiled layer in the optimised graph
+    armnn::Graph& optimisedGraph = GetGraphForTesting(optimizedNet.get());
+    Layer* preCompiledLayer = nullptr;
+    for (auto& layer : optimisedGraph)
+    {
+        if (layer->GetType() == LayerType::PreCompiled)
+        {
+            preCompiledLayer = layer;
+        }
+    }
+    CHECK(preCompiledLayer != nullptr);
+
+    // Create the TensorHandles.
+    CreateTensorHandles(optimisedGraph, factory);
+
+    // Make the workload and check it.
+    auto workload = MakeAndCheckWorkload<PreCompiledWorkload>(*preCompiledLayer, factory);
+
+    PreCompiledQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size()  == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns the workload so we can do extra, backend-specific tests.
+    // NOTE: We need to return the optimised network as well, otherwise it gets
+    // out of scope and the tensor handles get destructed
+    return std::make_pair(std::move(optimizedNet), std::move(workload));
+}
+
+template<typename ConstantWorkload, armnn::DataType DataType>
+std::unique_ptr<ConstantWorkload> CreateConstantWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                             armnn::Graph& graph,
+                                                             const armnn::TensorShape& outputShape)
+{
+    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
+
+    // create constant layer
+    auto constant = graph.AddLayer<ConstantLayer>("constant");
+    CHECK(constant);
+    constant->m_LayerOutput = std::make_unique<ScopedTensorHandle>(outputTensorInfo);
+
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Adds connections.
+    // connect constant to output
+    Connect(constant, output, outputTensorInfo, 0, 0);
+
+    // create tensor handles
+    CreateTensorHandles(graph, factory);
+
+    // create Constant workload"
+    auto workloadConstant = MakeAndCheckWorkload<ConstantWorkload>(*constant, factory);
+    CHECK(workloadConstant);
+
+    return workloadConstant;
+}
+
+template <typename PreluWorkload>
+std::unique_ptr<PreluWorkload> CreatePreluWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                       armnn::Graph& graph,
+                                                       const armnn::TensorShape& inputShape,
+                                                       const armnn::TensorShape& alphaShape,
+                                                       const armnn::TensorShape& outputShape,
+                                                       armnn::DataType dataType)
+{
+    // Creates the PReLU layer
+    Layer* const layer = graph.AddLayer<PreluLayer>("prelu");
+    CHECK(layer != nullptr);
+
+    // Creates extra layers
+    Layer* const input  = graph.AddLayer<InputLayer> (0, "input");
+    Layer* const alpha  = graph.AddLayer<InputLayer> (1, "alpha");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+    CHECK(input  != nullptr);
+    CHECK(alpha  != nullptr);
+    CHECK(output != nullptr);
+
+    // Connects up
+    armnn::TensorInfo inputTensorInfo (inputShape,  dataType);
+    armnn::TensorInfo alphaTensorInfo (alphaShape,  dataType);
+    armnn::TensorInfo outputTensorInfo(outputShape, dataType);
+    Connect(input, layer,  inputTensorInfo,  0, 0);
+    Connect(alpha, layer,  alphaTensorInfo,  0, 1);
+    Connect(layer, output, outputTensorInfo, 0, 0);
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it
+    auto workload = MakeAndCheckWorkload<PreluWorkload>(*layer, factory);
+
+    PreluQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 2);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    // Returns so we can do extra, backend-specific tests.
+    return workload;
+}
+
+template <typename SpaceToDepthWorkload, armnn::DataType DataType>
+std::unique_ptr<SpaceToDepthWorkload> CreateSpaceToDepthWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                                     armnn::Graph&  graph)
+{
+    SpaceToDepthDescriptor desc;
+    desc.m_BlockSize = 2;
+    Layer* const layer = graph.AddLayer<SpaceToDepthLayer>(desc, "spaceToDepth");
+
+    // Creates extra layers.
+    Layer* const input = graph.AddLayer<InputLayer>(0, "input");
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+
+    // Connects up.
+    armnn::TensorInfo inputTensorInfo({ 1, 2, 2, 1 }, DataType);
+    armnn::TensorInfo outputTensorInfo({ 1, 1, 1, 4 }, DataType);
+
+    Connect(input, layer, inputTensorInfo);
+    Connect(layer, output, outputTensorInfo);
+
+    CreateTensorHandles(graph, factory);
+
+    // Makes the workload and checks it.
+    auto workload = MakeAndCheckWorkload<SpaceToDepthWorkload>(*layer, factory);
+
+    SpaceToDepthQueueDescriptor queueDescriptor = workload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == 1);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    return workload;
+}
+
+template <typename StackWorkload, armnn::DataType DataType>
+std::unique_ptr<StackWorkload> CreateStackWorkloadTest(armnn::IWorkloadFactory& factory,
+                                                       armnn::Graph& graph,
+                                                       const armnn::TensorShape& inputShape,
+                                                       const armnn::TensorShape& outputShape,
+                                                       unsigned int axis,
+                                                       unsigned int numInputs)
+{
+    armnn::TensorInfo inputTensorInfo(inputShape, DataType);
+    armnn::TensorInfo outputTensorInfo(outputShape, DataType);
+
+    // Constructs the Stack layer.
+    armnn::StackDescriptor descriptor(axis, numInputs, inputShape);
+    Layer* const stackLayer = graph.AddLayer<StackLayer>(descriptor, "stack");
+    CHECK(stackLayer != nullptr);
+
+    // Constructs layer inputs and output.
+    std::vector<Layer*> inputs;
+    for (unsigned int i=0; i<numInputs; ++i)
+    {
+        inputs.push_back(graph.AddLayer<InputLayer>(
+            static_cast<int>(i),
+            ("input" + std::to_string(i)).c_str()
+        ));
+        CHECK(inputs[i] != nullptr);
+    }
+    Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
+    CHECK(output != nullptr);
+
+    // Adds connections.
+    for (unsigned int i=0; i<numInputs; ++i)
+    {
+        Connect(inputs[i], stackLayer, inputTensorInfo, 0, i);
+    }
+    Connect(stackLayer, output, outputTensorInfo, 0, 0);
+
+    CreateTensorHandles(graph, factory);
+
+    auto stackWorkload = MakeAndCheckWorkload<StackWorkload>(*stackLayer, factory);
+    StackQueueDescriptor queueDescriptor = stackWorkload->GetData();
+    CHECK(queueDescriptor.m_Inputs.size() == numInputs);
+    CHECK(queueDescriptor.m_Outputs.size() == 1);
+
+    return stackWorkload;
+}
+
+} // Anonymous namespace
diff --git a/src/armnnTestUtils/DataTypeUtils.hpp b/src/armnnTestUtils/DataTypeUtils.hpp
new file mode 100644
index 0000000..528a573
--- /dev/null
+++ b/src/armnnTestUtils/DataTypeUtils.hpp
@@ -0,0 +1,45 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <ResolveType.hpp>
+
+
+#include <reference/workloads/Encoders.hpp>
+
+#include <vector>
+
+// Utility tenmplate to convert a collection of values to the correct type
+template <armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
+std::vector<T> ConvertToDataType(const std::vector<float>& input,
+                                 const armnn::TensorInfo& inputTensorInfo)
+{
+    std::vector<T> output(input.size());
+    auto outputTensorInfo = inputTensorInfo;
+    outputTensorInfo.SetDataType(ArmnnType);
+
+    std::unique_ptr<armnn::Encoder<float>> pOutputEncoder = armnn::MakeEncoder<float>(outputTensorInfo, output.data());
+    armnn::Encoder<float>& rOutputEncoder = *pOutputEncoder;
+
+    for (auto it = input.begin(); it != input.end(); ++it)
+    {
+        rOutputEncoder.Set(*it);
+        ++rOutputEncoder;
+    }
+    return output;
+}
+
+// Utility tenmplate to convert a single value to the correct type
+template <typename T>
+T ConvertToDataType(const float& value,
+                    const armnn::TensorInfo& tensorInfo)
+{
+    std::vector<T> output(1);
+    std::unique_ptr<armnn::Encoder<float>> pEncoder = armnn::MakeEncoder<float>(tensorInfo, output.data());
+    armnn::Encoder<float>& rEncoder = *pEncoder;
+    rEncoder.Set(value);
+    return output[0];
+}
diff --git a/src/armnn/test/GraphUtils.cpp b/src/armnnTestUtils/GraphUtils.cpp
similarity index 96%
rename from src/armnn/test/GraphUtils.cpp
rename to src/armnnTestUtils/GraphUtils.cpp
index bc6b562..15dc888 100644
--- a/src/armnn/test/GraphUtils.cpp
+++ b/src/armnnTestUtils/GraphUtils.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
diff --git a/src/armnnTestUtils/GraphUtils.hpp b/src/armnnTestUtils/GraphUtils.hpp
new file mode 100644
index 0000000..95f0704
--- /dev/null
+++ b/src/armnnTestUtils/GraphUtils.hpp
@@ -0,0 +1,25 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <Graph.hpp>
+
+#include <string>
+
+
+bool GraphHasNamedLayer(const armnn::Graph& graph, const std::string& name);
+
+armnn::Layer* GetFirstLayerWithName(armnn::Graph& graph, const std::string& name);
+
+bool CheckNumberOfInputSlot(armnn::Layer* layer, unsigned int num);
+
+bool CheckNumberOfOutputSlot(armnn::Layer* layer, unsigned int num);
+
+bool IsConnected(armnn::Layer* srcLayer, armnn::Layer* destLayer,
+                 unsigned int srcSlot, unsigned int destSlot,
+                 const armnn::TensorInfo& expectedTensorInfo);
+
+bool CheckOrder(const armnn::Graph& graph, const armnn::Layer* first, const armnn::Layer* second);
+
diff --git a/src/backends/backendsCommon/test/TensorCopyUtils.cpp b/src/armnnTestUtils/TensorCopyUtils.cpp
similarity index 81%
rename from src/backends/backendsCommon/test/TensorCopyUtils.cpp
rename to src/armnnTestUtils/TensorCopyUtils.cpp
index ba7208c..14c6d5c 100644
--- a/src/backends/backendsCommon/test/TensorCopyUtils.cpp
+++ b/src/armnnTestUtils/TensorCopyUtils.cpp
@@ -1,9 +1,9 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
-#include "TensorCopyUtils.hpp"
+#include <armnnTestUtils/TensorCopyUtils.hpp>
 #include <Half.hpp>
 
 void CopyDataToITensorHandle(armnn::ITensorHandle* tensorHandle, const void* memory)
diff --git a/src/armnnTestUtils/TensorHelpers.hpp b/src/armnnTestUtils/TensorHelpers.hpp
new file mode 100644
index 0000000..d51e4b1
--- /dev/null
+++ b/src/armnnTestUtils/TensorHelpers.hpp
@@ -0,0 +1,235 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <armnnTestUtils/PredicateResult.hpp>
+
+#include <armnn/Tensor.hpp>
+#include <armnn/utility/Assert.hpp>
+#include <armnnUtils/FloatingPointComparison.hpp>
+
+#include <QuantizeHelper.hpp>
+
+#include <doctest/doctest.h>
+
+#include <array>
+#include <cmath>
+#include <random>
+#include <vector>
+
+constexpr float g_FloatCloseToZeroTolerance = 1.0e-6f;
+
+template<typename T, bool isQuantized = true>
+struct SelectiveComparer
+{
+    static bool Compare(T a, T b)
+    {
+        return (std::max(a, b) - std::min(a, b)) <= 1;
+    }
+
+};
+
+template<typename T>
+struct SelectiveComparer<T, false>
+{
+    static bool Compare(T a, T b)
+    {
+        // If a or b is zero, percent_tolerance does an exact match, so compare to a small, constant tolerance instead.
+        if (a == 0.0f || b == 0.0f)
+        {
+            return std::abs(a - b) <= g_FloatCloseToZeroTolerance;
+        }
+
+        if (std::isinf(a) && a == b)
+        {
+            return true;
+        }
+
+        if (std::isnan(a) && std::isnan(b))
+        {
+            return true;
+        }
+
+        // For unquantized floats we use a tolerance of 1%.
+        return armnnUtils::within_percentage_tolerance(a, b);
+    }
+};
+
+template<typename T>
+bool SelectiveCompare(T a, T b)
+{
+    return SelectiveComparer<T, armnn::IsQuantizedType<T>()>::Compare(a, b);
+};
+
+template<typename T>
+bool SelectiveCompareBoolean(T a, T b)
+{
+    return (((a == 0) && (b == 0)) || ((a != 0) && (b != 0)));
+};
+
+template <typename T>
+armnn::PredicateResult CompareTensors(const std::vector<T>& actualData,
+                                      const std::vector<T>& expectedData,
+                                      const armnn::TensorShape& actualShape,
+                                      const armnn::TensorShape& expectedShape,
+                                      bool compareBoolean = false,
+                                      bool isDynamic = false)
+{
+    if (actualData.size() != expectedData.size())
+    {
+        armnn::PredicateResult res(false);
+        res.Message() << "Different data size ["
+                      << actualData.size()
+                      << "!="
+                      << expectedData.size()
+                      << "]";
+        return res;
+    }
+
+    if (actualShape.GetNumDimensions() != expectedShape.GetNumDimensions())
+    {
+        armnn::PredicateResult res(false);
+        res.Message() << "Different number of dimensions ["
+                      << actualShape.GetNumDimensions()
+                      << "!="
+                      << expectedShape.GetNumDimensions()
+                      << "]";
+        return res;
+    }
+
+    if (actualShape.GetNumElements() != expectedShape.GetNumElements())
+    {
+        armnn::PredicateResult res(false);
+        res.Message() << "Different number of elements ["
+                      << actualShape.GetNumElements()
+                      << "!="
+                      << expectedShape.GetNumElements()
+                      << "]";
+        return res;
+    }
+
+    unsigned int numberOfDimensions = actualShape.GetNumDimensions();
+
+    if (!isDynamic)
+    {
+        // Checks they are same shape.
+        for (unsigned int i = 0; i < numberOfDimensions; ++i)
+        {
+            if (actualShape[i] != expectedShape[i])
+            {
+                armnn::PredicateResult res(false);
+                res.Message() << "Different shapes ["
+                              << actualShape[i]
+                              << "!="
+                              << expectedShape[i]
+                              << "]";
+                return res;
+            }
+        }
+    }
+
+    // Fun iteration over n dimensions.
+    std::vector<unsigned int> indices;
+    for (unsigned int i = 0; i < numberOfDimensions; i++)
+    {
+        indices.emplace_back(0);
+    }
+
+    std::stringstream errorString;
+    int numFailedElements = 0;
+    constexpr int maxReportedDifferences = 3;
+    unsigned int index = 0;
+
+    // Compare data element by element.
+    while (true)
+    {
+        bool comparison;
+        // As true for uint8_t is non-zero (1-255) we must have a dedicated compare for Booleans.
+        if(compareBoolean)
+        {
+            comparison = SelectiveCompareBoolean(actualData[index], expectedData[index]);
+        }
+        else
+        {
+            comparison = SelectiveCompare(actualData[index], expectedData[index]);
+        }
+
+        if (!comparison)
+        {
+            ++numFailedElements;
+
+            if (numFailedElements <= maxReportedDifferences)
+            {
+                if (numFailedElements >= 2)
+                {
+                    errorString << ", ";
+                }
+                errorString << "[";
+                for (unsigned int i = 0; i < numberOfDimensions; ++i)
+                {
+                    errorString << indices[i];
+                    if (i != numberOfDimensions - 1)
+                    {
+                        errorString << ",";
+                    }
+                }
+                errorString << "]";
+
+                errorString << " (" << +actualData[index] << " != " << +expectedData[index] << ")";
+            }
+        }
+
+        ++indices[numberOfDimensions - 1];
+        for (unsigned int i=numberOfDimensions-1; i>0; i--)
+        {
+            if (indices[i] == actualShape[i])
+            {
+                indices[i] = 0;
+                ++indices[i - 1];
+            }
+        }
+        if (indices[0] == actualShape[0])
+        {
+            break;
+        }
+
+        index++;
+    }
+
+    armnn::PredicateResult comparisonResult(true);
+    if (numFailedElements > 0)
+    {
+        comparisonResult.SetResult(false);
+        comparisonResult.Message() << numFailedElements << " different values at: ";
+        if (numFailedElements > maxReportedDifferences)
+        {
+            errorString << ", ... (and " << (numFailedElements - maxReportedDifferences) << " other differences)";
+        }
+        comparisonResult.Message() << errorString.str();
+    }
+
+    return comparisonResult;
+}
+
+template <typename T>
+std::vector<T> MakeRandomTensor(const armnn::TensorInfo& tensorInfo,
+                                unsigned int seed,
+                                float        min = -10.0f,
+                                float        max = 10.0f)
+{
+    std::mt19937 gen(seed);
+    std::uniform_real_distribution<float> dist(min, max);
+
+    std::vector<float> init(tensorInfo.GetNumElements());
+    for (unsigned int i = 0; i < init.size(); i++)
+    {
+        init[i] = dist(gen);
+    }
+
+    const float   qScale  = tensorInfo.GetQuantizationScale();
+    const int32_t qOffset = tensorInfo.GetQuantizationOffset();
+
+    return armnnUtils::QuantizedVector<T>(init, qScale, qOffset);
+}
diff --git a/src/armnn/test/TestUtils.cpp b/src/armnnTestUtils/TestUtils.cpp
similarity index 95%
rename from src/armnn/test/TestUtils.cpp
rename to src/armnnTestUtils/TestUtils.cpp
index 97cc80c..9ac0b39 100644
--- a/src/armnn/test/TestUtils.cpp
+++ b/src/armnnTestUtils/TestUtils.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
diff --git a/src/armnnTestUtils/TestUtils.hpp b/src/armnnTestUtils/TestUtils.hpp
new file mode 100644
index 0000000..d5b6d1b
--- /dev/null
+++ b/src/armnnTestUtils/TestUtils.hpp
@@ -0,0 +1,58 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <armnn/INetwork.hpp>
+#include <Graph.hpp>
+#include <Runtime.hpp>
+
+void Connect(armnn::IConnectableLayer* from, armnn::IConnectableLayer* to, const armnn::TensorInfo& tensorInfo,
+             unsigned int fromIndex = 0, unsigned int toIndex = 0);
+
+template <typename LayerT>
+bool IsLayerOfType(const armnn::Layer* const layer)
+{
+    return (layer->GetType() == armnn::LayerEnumOf<LayerT>());
+}
+
+inline bool CheckSequence(const armnn::Graph::ConstIterator first, const armnn::Graph::ConstIterator last)
+{
+    return (first == last);
+}
+
+/// Checks each unary function in Us evaluates true for each correspondent layer in the sequence [first, last).
+template <typename U, typename... Us>
+bool CheckSequence(const armnn::Graph::ConstIterator first, const armnn::Graph::ConstIterator last, U&& u, Us&&... us)
+{
+    return u(*first) && CheckSequence(std::next(first), last, us...);
+}
+
+template <typename LayerT>
+bool CheckRelatedLayers(armnn::Graph& graph, const std::list<std::string>& testRelatedLayers)
+{
+    for (auto& layer : graph)
+    {
+        if (layer->GetType() == armnn::LayerEnumOf<LayerT>())
+        {
+            auto& relatedLayers = layer->GetRelatedLayerNames();
+            if (!std::equal(relatedLayers.begin(), relatedLayers.end(), testRelatedLayers.begin(),
+                            testRelatedLayers.end()))
+            {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+namespace armnn
+{
+Graph& GetGraphForTesting(IOptimizedNetwork* optNetPtr);
+ModelOptions& GetModelOptionsForTesting(IOptimizedNetwork* optNetPtr);
+profiling::ProfilingService& GetProfilingService(RuntimeImpl* runtime);
+
+} // namespace armnn
\ No newline at end of file
diff --git a/src/armnn/test/UnitTests.cpp b/src/armnnTestUtils/UnitTests.cpp
similarity index 100%
rename from src/armnn/test/UnitTests.cpp
rename to src/armnnTestUtils/UnitTests.cpp
diff --git a/src/armnnTestUtils/UnitTests.hpp b/src/armnnTestUtils/UnitTests.hpp
new file mode 100644
index 0000000..788ad87
--- /dev/null
+++ b/src/armnnTestUtils/UnitTests.hpp
@@ -0,0 +1,191 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include "TensorHelpers.hpp"
+#include "WorkloadTestUtils.hpp"
+
+#include <armnn/Logging.hpp>
+#include <armnn/Utils.hpp>
+#include <reference/RefWorkloadFactory.hpp>
+#include <reference/test/RefWorkloadFactoryHelper.hpp>
+
+#include <backendsCommon/test/WorkloadFactoryHelper.hpp>
+
+#include <armnnTestUtils/LayerTestResult.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+
+#include <doctest/doctest.h>
+
+inline void ConfigureLoggingTest()
+{
+    // Configures logging for both the ARMNN library and this test program.
+    armnn::ConfigureLogging(true, true, armnn::LogSeverity::Fatal);
+}
+
+// The following macros require the caller to have defined FactoryType, with one of the following using statements:
+//
+//      using FactoryType = armnn::RefWorkloadFactory;
+//      using FactoryType = armnn::ClWorkloadFactory;
+//      using FactoryType = armnn::NeonWorkloadFactory;
+
+/// Executes CHECK_MESSAGE on CompareTensors() return value so that the predicate_result message is reported.
+/// If the test reports itself as not supported then the tensors are not compared.
+/// Additionally this checks that the supportedness reported by the test matches the name of the test.
+/// Unsupported tests must be 'tagged' by including "UNSUPPORTED" in their name.
+/// This is useful because it clarifies that the feature being tested is not actually supported
+/// (a passed test with the name of a feature would imply that feature was supported).
+/// If support is added for a feature, the test case will fail because the name incorrectly contains UNSUPPORTED.
+/// If support is removed for a feature, the test case will fail because the name doesn't contain UNSUPPORTED.
+template <typename T, std::size_t n>
+void CompareTestResultIfSupported(const std::string& testName, const LayerTestResult<T, n>& testResult)
+{
+    bool testNameIndicatesUnsupported = testName.find("UNSUPPORTED") != std::string::npos;
+    CHECK_MESSAGE(testNameIndicatesUnsupported != testResult.m_Supported,
+                  "The test name does not match the supportedness it is reporting");
+    if (testResult.m_Supported)
+    {
+        auto result = CompareTensors(testResult.m_ActualData,
+                                     testResult.m_ExpectedData,
+                                     testResult.m_ActualShape,
+                                     testResult.m_ExpectedShape,
+                                     testResult.m_CompareBoolean);
+       CHECK_MESSAGE(result.m_Result, result.m_Message.str());
+    }
+}
+
+template <typename T, std::size_t n>
+void CompareTestResultIfSupported(const std::string& testName, const std::vector<LayerTestResult<T, n>>& testResult)
+{
+    bool testNameIndicatesUnsupported = testName.find("UNSUPPORTED") != std::string::npos;
+    for (unsigned int i = 0; i < testResult.size(); ++i)
+    {
+        CHECK_MESSAGE(testNameIndicatesUnsupported != testResult[i].m_Supported,
+                      "The test name does not match the supportedness it is reporting");
+        if (testResult[i].m_Supported)
+        {
+            auto result = CompareTensors(testResult[i].m_ActualData,
+                                         testResult[i].m_ExpectedData,
+                                         testResult[i].m_ActualShape,
+                                         testResult[i].m_ExpectedShape);
+            CHECK_MESSAGE(result.m_Result, result.m_Message.str());
+        }
+    }
+}
+
+template<typename FactoryType, typename TFuncPtr, typename... Args>
+void RunTestFunction(const char* testName, TFuncPtr testFunction, Args... args)
+{
+    std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
+    armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
+
+    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
+    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
+
+    auto testResult = (*testFunction)(workloadFactory, memoryManager, args...);
+    CompareTestResultIfSupported(testName, testResult);
+
+    armnn::ProfilerManager::GetInstance().RegisterProfiler(nullptr);
+}
+
+
+template<typename FactoryType, typename TFuncPtr, typename... Args>
+void RunTestFunctionUsingTensorHandleFactory(const char* testName, TFuncPtr testFunction, Args... args)
+{
+    std::unique_ptr<armnn::IProfiler> profiler = std::make_unique<armnn::IProfiler>();
+    armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
+
+    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
+    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
+
+    auto tensorHandleFactory = WorkloadFactoryHelper<FactoryType>::GetTensorHandleFactory(memoryManager);
+
+    auto testResult = (*testFunction)(workloadFactory, memoryManager, tensorHandleFactory, args...);
+    CompareTestResultIfSupported(testName, testResult);
+
+    armnn::ProfilerManager::GetInstance().RegisterProfiler(nullptr);
+}
+
+#define ARMNN_SIMPLE_TEST_CASE(TestName, TestFunction) \
+    TEST_CASE(#TestName) \
+    { \
+        TestFunction(); \
+    }
+
+#define ARMNN_AUTO_TEST_CASE(TestName, TestFunction, ...) \
+    TEST_CASE(#TestName) \
+    { \
+        RunTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
+#define ARMNN_AUTO_TEST_FIXTURE(TestName, Fixture, TestFunction, ...) \
+    TEST_CASE_FIXTURE(Fixture, #TestName) \
+    { \
+        RunTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
+#define ARMNN_AUTO_TEST_CASE_WITH_THF(TestName, TestFunction, ...) \
+    TEST_CASE(#TestName) \
+    { \
+        RunTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
+#define ARMNN_AUTO_TEST_FIXTURE_WITH_THF(TestName, Fixture, TestFunction, ...) \
+    TEST_CASE_FIXTURE(Fixture, #TestName) \
+    { \
+        RunTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
+template<typename FactoryType, typename TFuncPtr, typename... Args>
+void CompareRefTestFunction(const char* testName, TFuncPtr testFunction, Args... args)
+{
+    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
+    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
+
+    armnn::RefWorkloadFactory refWorkloadFactory;
+
+    auto testResult = (*testFunction)(workloadFactory, memoryManager, refWorkloadFactory, args...);
+    CompareTestResultIfSupported(testName, testResult);
+}
+
+template<typename FactoryType, typename TFuncPtr, typename... Args>
+void CompareRefTestFunctionUsingTensorHandleFactory(const char* testName, TFuncPtr testFunction, Args... args)
+{
+    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
+    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
+
+    armnn::RefWorkloadFactory refWorkloadFactory;
+    auto tensorHandleFactory = WorkloadFactoryHelper<FactoryType>::GetTensorHandleFactory(memoryManager);
+    auto refTensorHandleFactory =
+        RefWorkloadFactoryHelper::GetTensorHandleFactory(memoryManager);
+
+    auto testResult = (*testFunction)(
+        workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, args...);
+    CompareTestResultIfSupported(testName, testResult);
+}
+
+#define ARMNN_COMPARE_REF_AUTO_TEST_CASE(TestName, TestFunction, ...) \
+    TEST_CASE(#TestName) \
+    { \
+        CompareRefTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
+#define ARMNN_COMPARE_REF_AUTO_TEST_CASE_WITH_THF(TestName, TestFunction, ...) \
+    TEST_CASE(#TestName) \
+    { \
+        CompareRefTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
+#define ARMNN_COMPARE_REF_FIXTURE_TEST_CASE(TestName, Fixture, TestFunction, ...) \
+    TEST_CASE_FIXTURE(Fixture, #TestName) \
+    { \
+        CompareRefTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
+#define ARMNN_COMPARE_REF_FIXTURE_TEST_CASE_WITH_THF(TestName, Fixture, TestFunction, ...) \
+    TEST_CASE_FIXTURE(Fixture, #TestName) \
+    { \
+        CompareRefTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
diff --git a/src/armnnTestUtils/WorkloadTestUtils.hpp b/src/armnnTestUtils/WorkloadTestUtils.hpp
new file mode 100644
index 0000000..856e54a
--- /dev/null
+++ b/src/armnnTestUtils/WorkloadTestUtils.hpp
@@ -0,0 +1,113 @@
+//
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <armnn/Tensor.hpp>
+
+#include <armnn/backends/IBackendInternal.hpp>
+#include <armnn/backends/IMemoryManager.hpp>
+#include <backendsCommon/Workload.hpp>
+#include <backendsCommon/WorkloadInfo.hpp>
+
+namespace armnn
+{
+class ITensorHandle;
+} // namespace armnn
+
+namespace
+{
+
+template <typename QueueDescriptor>
+void AddInputToWorkload(QueueDescriptor& descriptor,
+    armnn::WorkloadInfo& info,
+    const armnn::TensorInfo& tensorInfo,
+    armnn::ITensorHandle* tensorHandle)
+{
+    descriptor.m_Inputs.push_back(tensorHandle);
+    info.m_InputTensorInfos.push_back(tensorInfo);
+}
+
+template <typename QueueDescriptor>
+void AddOutputToWorkload(QueueDescriptor& descriptor,
+    armnn::WorkloadInfo& info,
+    const armnn::TensorInfo& tensorInfo,
+    armnn::ITensorHandle* tensorHandle)
+{
+    descriptor.m_Outputs.push_back(tensorHandle);
+    info.m_OutputTensorInfos.push_back(tensorInfo);
+}
+
+template <typename QueueDescriptor>
+void SetWorkloadInput(QueueDescriptor& descriptor,
+    armnn::WorkloadInfo& info,
+    unsigned int index,
+    const armnn::TensorInfo& tensorInfo,
+    armnn::ITensorHandle* tensorHandle)
+{
+    descriptor.m_Inputs[index] = tensorHandle;
+    info.m_InputTensorInfos[index] = tensorInfo;
+}
+
+template <typename QueueDescriptor>
+void SetWorkloadOutput(QueueDescriptor& descriptor,
+    armnn::WorkloadInfo& info,
+    unsigned int index,
+    const armnn::TensorInfo& tensorInfo,
+    armnn::ITensorHandle* tensorHandle)
+{
+    descriptor.m_Outputs[index] = tensorHandle;
+    info.m_OutputTensorInfos[index] = tensorInfo;
+}
+
+inline void ExecuteWorkload(armnn::IWorkload& workload,
+                            const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
+                            bool memoryManagementRequested = true)
+{
+    const bool manageMemory = memoryManager && memoryManagementRequested;
+
+    // Acquire working memory (if needed)
+    if (manageMemory)
+    {
+        memoryManager->Acquire();
+    }
+
+    // Perform PostAllocationConfiguration
+    workload.PostAllocationConfigure();
+
+    // Execute the workload
+    workload.Execute();
+
+    // Release working memory (if needed)
+    if (manageMemory)
+    {
+        memoryManager->Release();
+    }
+}
+
+inline armnn::Optional<armnn::DataType> GetBiasTypeFromWeightsType(armnn::Optional<armnn::DataType> weightsType)
+{
+    if (!weightsType)
+    {
+        return weightsType;
+    }
+
+    switch(weightsType.value())
+    {
+        case armnn::DataType::BFloat16:
+        case armnn::DataType::Float16:
+        case armnn::DataType::Float32:
+            return weightsType;
+        case armnn::DataType::QAsymmS8:
+        case armnn::DataType::QAsymmU8:
+        case armnn::DataType::QSymmS8:
+        case armnn::DataType::QSymmS16:
+            return armnn::DataType::Signed32;
+        default:
+            ARMNN_ASSERT_MSG(false, "GetBiasTypeFromWeightsType(): Unsupported data type.");
+    }
+    return armnn::EmptyOptional();
+}
+
+} // anonymous namespace
diff --git a/src/armnnTfLiteParser/test/DetectionPostProcess.cpp b/src/armnnTfLiteParser/test/DetectionPostProcess.cpp
index 4000d49..5dc78c6 100644
--- a/src/armnnTfLiteParser/test/DetectionPostProcess.cpp
+++ b/src/armnnTfLiteParser/test/DetectionPostProcess.cpp
@@ -6,7 +6,7 @@
 #include "ParserFlatbuffersFixture.hpp"
 #include "ParserPrototxtFixture.hpp"
 #include "ParserHelper.hpp"
-#include "test/GraphUtils.hpp"
+#include <GraphUtils.hpp>
 
 #include <armnn/utility/PolymorphicDowncast.hpp>
 #include <QuantizeHelper.hpp>
diff --git a/src/armnnTfLiteParser/test/ParserFlatbuffersFixture.hpp b/src/armnnTfLiteParser/test/ParserFlatbuffersFixture.hpp
index 871f647..6b35558 100644
--- a/src/armnnTfLiteParser/test/ParserFlatbuffersFixture.hpp
+++ b/src/armnnTfLiteParser/test/ParserFlatbuffersFixture.hpp
@@ -17,7 +17,7 @@
 
 #include <ResolveType.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <fmt/format.h>
 #include <doctest/doctest.h>
diff --git a/src/armnnUtils/ParserPrototxtFixture.hpp b/src/armnnUtils/ParserPrototxtFixture.hpp
index 76e65df..31ee829 100644
--- a/src/armnnUtils/ParserPrototxtFixture.hpp
+++ b/src/armnnUtils/ParserPrototxtFixture.hpp
@@ -6,7 +6,7 @@
 #pragma once
 
 #include <armnn/IRuntime.hpp>
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <Network.hpp>
 #include <VerificationHelpers.hpp>
diff --git a/src/backends/aclCommon/test/CMakeLists.txt b/src/backends/aclCommon/test/CMakeLists.txt
index 756ef4a..7eb232a 100644
--- a/src/backends/aclCommon/test/CMakeLists.txt
+++ b/src/backends/aclCommon/test/CMakeLists.txt
@@ -13,6 +13,7 @@
 add_library(armnnAclCommonUnitTests OBJECT ${armnnAclCommonUnitTests_sources})
 target_include_directories(armnnAclCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
 target_include_directories(armnnAclCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
+target_include_directories(armnnAclCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnTestUtils)
 target_include_directories(armnnAclCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
 target_include_directories(armnnAclCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
 target_include_directories(armnnAclCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
diff --git a/src/backends/aclCommon/test/CreateWorkloadClNeon.hpp b/src/backends/aclCommon/test/CreateWorkloadClNeon.hpp
index bdae998..6a0d5cf 100644
--- a/src/backends/aclCommon/test/CreateWorkloadClNeon.hpp
+++ b/src/backends/aclCommon/test/CreateWorkloadClNeon.hpp
@@ -4,8 +4,8 @@
 //
 #pragma once
 
-#include <test/CreateWorkload.hpp>
-#include <test/PredicateResult.hpp>
+#include <CreateWorkload.hpp>
+#include <armnnTestUtils/PredicateResult.hpp>
 #include <armnn/utility/PolymorphicDowncast.hpp>
 #include <backendsCommon/MemCopyWorkload.hpp>
 #include <reference/RefWorkloadFactory.hpp>
diff --git a/src/backends/aclCommon/test/MemCopyTestImpl.hpp b/src/backends/aclCommon/test/MemCopyTestImpl.hpp
index 91ba4ea..d943cfd 100644
--- a/src/backends/aclCommon/test/MemCopyTestImpl.hpp
+++ b/src/backends/aclCommon/test/MemCopyTestImpl.hpp
@@ -5,15 +5,14 @@
 #pragma once
 
 #include <ResolveType.hpp>
-
 #include <armnn/backends/IBackendInternal.hpp>
 
-#include <backendsCommon/test/LayerTests.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadFactoryHelper.hpp>
+#include <test/TensorHelpers.hpp>
 #include <backendsCommon/test/WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <armnnTestUtils/LayerTestResult.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <backendsCommon/test/WorkloadFactoryHelper.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/WorkloadFactory.cpp b/src/backends/backendsCommon/WorkloadFactory.cpp
index ef2a348..93932a8 100644
--- a/src/backends/backendsCommon/WorkloadFactory.cpp
+++ b/src/backends/backendsCommon/WorkloadFactory.cpp
@@ -8,6 +8,7 @@
 
 #include <armnn/Types.hpp>
 #include <armnn/LayerSupport.hpp>
+#include <armnn/backends/IBackendInternal.hpp>
 #include <armnn/backends/ILayerSupport.hpp>
 #include <armnn/BackendHelper.hpp>
 #include <armnn/BackendRegistry.hpp>
@@ -17,7 +18,7 @@
 #include <backendsCommon/WorkloadFactory.hpp>
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+//#include <WorkloadTestUtils.hpp>
 
 #include <sstream>
 
@@ -45,6 +46,31 @@
 
 } // anonymous namespace
 
+inline armnn::Optional<armnn::DataType> GetBiasTypeFromWeightsType(armnn::Optional<armnn::DataType> weightsType)
+{
+    if (!weightsType)
+    {
+        return weightsType;
+    }
+
+    switch(weightsType.value())
+    {
+        case armnn::DataType::BFloat16:
+        case armnn::DataType::Float16:
+        case armnn::DataType::Float32:
+            return weightsType;
+        case armnn::DataType::QAsymmS8:
+        case armnn::DataType::QAsymmU8:
+        case armnn::DataType::QSymmS8:
+        case armnn::DataType::QSymmS16:
+            return armnn::DataType::Signed32;
+        default:
+            ARMNN_ASSERT_MSG(false, "GetBiasTypeFromWeightsType(): Unsupported data type.");
+    }
+    return armnn::EmptyOptional();
+}
+
+
 bool IWorkloadFactory::IsLayerConfigurationSupported(const BackendId& backendId,
                                                      const IConnectableLayer& connectableLayer,
                                                      Optional<DataType> dataType,
diff --git a/src/backends/backendsCommon/common.mk b/src/backends/backendsCommon/common.mk
index 206faf5..8f97669 100644
--- a/src/backends/backendsCommon/common.mk
+++ b/src/backends/backendsCommon/common.mk
@@ -35,7 +35,6 @@
 # up by the Android.mk file in the root of ArmNN
 
 COMMON_TEST_SOURCES := \
-    test/CommonTestUtils.cpp \
     test/CustomMemoryOptimizerStrategyTests.cpp \
     test/InstanceNormalizationEndToEndTestImpl.cpp \
     test/JsonPrinterTestImpl.cpp \
@@ -43,7 +42,6 @@
     test/QLstmEndToEndTestImpl.cpp \
     test/QuantizedLstmEndToEndTestImpl.cpp \
     test/SpaceToDepthEndToEndTestImpl.cpp \
-    test/TensorCopyUtils.cpp \
     test/layerTests/AbsTestImpl.cpp \
     test/layerTests/ActivationTestImpl.cpp \
     test/layerTests/AdditionTestImpl.cpp \
diff --git a/src/backends/backendsCommon/test/ActivationEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ActivationEndToEndTestImpl.hpp
index f7d4596..10e8363 100644
--- a/src/backends/backendsCommon/test/ActivationEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/ActivationEndToEndTestImpl.hpp
@@ -8,7 +8,9 @@
 
 #include <armnn/INetwork.hpp>
 #include <armnn/TypesUtils.hpp>
-#include <backendsCommon/test/CommonTestUtils.hpp>
+
+#include <CommonTestUtils.hpp>
+
 #include <ResolveType.hpp>
 
 namespace
diff --git a/src/backends/backendsCommon/test/ActivationFixture.hpp b/src/backends/backendsCommon/test/ActivationFixture.hpp
index c61f3f0..caa67ac 100644
--- a/src/backends/backendsCommon/test/ActivationFixture.hpp
+++ b/src/backends/backendsCommon/test/ActivationFixture.hpp
@@ -4,12 +4,12 @@
 //
 #pragma once
 
-#include "TensorCopyUtils.hpp"
-#include "WorkloadTestUtils.hpp"
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
 #include <armnn/utility/NumericCast.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 struct ActivationFixture
 {
diff --git a/src/backends/backendsCommon/test/ArgMinMaxEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ArgMinMaxEndToEndTestImpl.hpp
index 041f9f8..1b65385 100644
--- a/src/backends/backendsCommon/test/ArgMinMaxEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/ArgMinMaxEndToEndTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <QuantizeHelper.hpp>
 #include <ResolveType.hpp>
diff --git a/src/backends/backendsCommon/test/BackendProfilingTests.cpp b/src/backends/backendsCommon/test/BackendProfilingTests.cpp
index 62c06fe..b40964c 100644
--- a/src/backends/backendsCommon/test/BackendProfilingTests.cpp
+++ b/src/backends/backendsCommon/test/BackendProfilingTests.cpp
@@ -14,7 +14,7 @@
 #include "ProfilingUtils.hpp"
 #include "RequestCounterDirectoryCommandHandler.hpp"
 
-#include <test/TestUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <armnn/utility/IgnoreUnused.hpp>
 #include <armnn/BackendId.hpp>
diff --git a/src/backends/backendsCommon/test/BatchToSpaceNdEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/BatchToSpaceNdEndToEndTestImpl.hpp
index 859694c..87fccd8 100644
--- a/src/backends/backendsCommon/test/BatchToSpaceNdEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/BatchToSpaceNdEndToEndTestImpl.hpp
@@ -8,7 +8,7 @@
 
 #include <armnn/INetwork.hpp>
 
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt
index 958f484..bb85f7e 100644
--- a/src/backends/backendsCommon/test/CMakeLists.txt
+++ b/src/backends/backendsCommon/test/CMakeLists.txt
@@ -10,12 +10,15 @@
     BackendIdTests.cpp
     BackendProfilingTests.cpp
     BackendRegistryTests.cpp
+    CommonTestUtils.hpp
     ChannelShuffleEndToEndTestImpl.hpp
     ComparisonEndToEndTestImpl.hpp
     CompatibilityTests.cpp
     ConcatEndToEndTestImpl.hpp
     Convolution3dEndToEndTestImpl.hpp
     CustomMemoryOptimizerStrategyTests.cpp
+    DataLayoutUtils.hpp
+    DataTypeUtils.hpp
     DefaultAsyncExecuteTest.cpp
     DepthToSpaceEndToEndTestImpl.hpp
     DequantizeEndToEndTestImpl.hpp
@@ -54,7 +57,9 @@
     SpaceToDepthEndToEndTestImpl.hpp
     SplitterEndToEndTestImpl.hpp
     StridedSliceAsyncEndToEndTest.hpp
+    TensorCopyUtils.hpp
     WorkloadFactoryHelper.hpp
+    WorkloadTestUtils.hpp
     layerTests/AbsTestImpl.cpp
     layerTests/AbsTestImpl.hpp
     layerTests/ActivationTestImpl.cpp
@@ -116,6 +121,7 @@
     layerTests/InstanceNormalizationTestImpl.hpp
     layerTests/L2NormalizationTestImpl.cpp
     layerTests/L2NormalizationTestImpl.hpp
+    layerTests/LayerTestResult.hpp
     layerTests/LogTestImpl.cpp
     layerTests/LogTestImpl.hpp
     layerTests/LogicalTestImpl.cpp
@@ -200,6 +206,7 @@
 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)
+target_include_directories(armnnBackendsCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnTestUtils)
 target_include_directories(armnnBackendsCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
 target_include_directories(armnnBackendsCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
 target_include_directories(armnnBackendsCommonUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
diff --git a/src/backends/backendsCommon/test/ChannelShuffleEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ChannelShuffleEndToEndTestImpl.hpp
index 7d46be7..27907f1 100644
--- a/src/backends/backendsCommon/test/ChannelShuffleEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/ChannelShuffleEndToEndTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <armnn/INetwork.hpp>
 #include <ResolveType.hpp>
diff --git a/src/backends/backendsCommon/test/CommonTestUtils.hpp b/src/backends/backendsCommon/test/CommonTestUtils.hpp
index 07523d7..72e3860 100644
--- a/src/backends/backendsCommon/test/CommonTestUtils.hpp
+++ b/src/backends/backendsCommon/test/CommonTestUtils.hpp
@@ -1,119 +1,12 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
-#pragma once
+// This file is deprecated and will be removed soon.
+// Please use the new header in armnnTestUtils instead.
+// This will use the new armnnTestUtils header.
+#include "../../../armnnTestUtils/CommonTestUtils.hpp"
 
-#include <Graph.hpp>
-#include <SubgraphView.hpp>
-#include <SubgraphViewSelector.hpp>
-#include <ResolveType.hpp>
-
-#include <armnn/BackendRegistry.hpp>
-
-#include <armnn/Types.hpp>
-#include <backendsCommon/TensorHandle.hpp>
-
-#include <test/TestUtils.hpp>
-
-#include <algorithm>
-#include <random>
-#include <vector>
-
-// Checks that two collections have the exact same contents (in any order)
-// The given collections do not have to contain duplicates
-// Cannot use std::sort here because std lists have their own std::list::sort method
-template <typename CollectionType>
-bool AreEqual(const CollectionType& lhs, const CollectionType& rhs)
-{
-    if (lhs.size() != rhs.size())
-    {
-        return false;
-    }
-
-    auto lhs_it = std::find_if(lhs.begin(), lhs.end(), [&rhs](auto& item)
-    {
-        return std::find(rhs.begin(), rhs.end(), item) == rhs.end();
-    });
-
-    return lhs_it == lhs.end();
-}
-
-// Checks that the given collection contains the specified item
-template <typename CollectionType>
-bool Contains(const CollectionType& collection, const typename CollectionType::value_type& item)
-{
-    return std::find(collection.begin(), collection.end(), item) != collection.end();
-}
-
-// Checks that the given map contains the specified key
-template <typename MapType>
-bool Contains(const MapType& map, const typename MapType::key_type& key)
-{
-    return map.find(key) != map.end();
-}
-
-// Utility template for comparing tensor elements
-template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
-inline bool Compare(T a, T b, float tolerance = 0.000001f)
-{
-    if (ArmnnType == armnn::DataType::Boolean)
-    {
-        // NOTE: Boolean is represented as uint8_t (with zero equals
-        // false and everything else equals true), therefore values
-        // need to be casted to bool before comparing them
-        return static_cast<bool>(a) == static_cast<bool>(b);
-    }
-
-    // NOTE: All other types can be cast to float and compared with
-    // a certain level of tolerance
-    return std::fabs(static_cast<float>(a) - static_cast<float>(b)) <= tolerance;
-}
-
-template <typename ConvolutionLayer>
-void SetWeightAndBias(ConvolutionLayer* layer, const armnn::TensorInfo& weightInfo, const armnn::TensorInfo& biasInfo)
-{
-    layer->m_Weight = std::make_unique<armnn::ScopedTensorHandle>(weightInfo);
-    layer->m_Bias   = std::make_unique<armnn::ScopedTensorHandle>(biasInfo);
-
-    layer->m_Weight->Allocate();
-    layer->m_Bias->Allocate();
-}
-
-armnn::SubgraphView::InputSlots CreateInputsFrom(const std::vector<armnn::Layer*>& layers);
-
-armnn::SubgraphView::OutputSlots CreateOutputsFrom(const std::vector<armnn::Layer*>& layers);
-
-armnn::SubgraphView::SubgraphViewPtr CreateSubgraphViewFrom(armnn::SubgraphView::InputSlots&& inputs,
-                                                            armnn::SubgraphView::OutputSlots&& outputs,
-                                                            armnn::SubgraphView::Layers&& layers);
-
-armnn::IBackendInternalUniquePtr CreateBackendObject(const armnn::BackendId& backendId);
-
-armnn::TensorShape MakeTensorShape(unsigned int batches,
-                                   unsigned int channels,
-                                   unsigned int height,
-                                   unsigned int width,
-                                   armnn::DataLayout layout);
-
-template<typename DataType>
-static std::vector<DataType> GenerateRandomData(size_t size)
-{
-    constexpr bool isIntegerType = std::is_integral<DataType>::value;
-    using Distribution =
-    typename std::conditional<isIntegerType,
-            std::uniform_int_distribution<DataType>,
-            std::uniform_real_distribution<DataType>>::type;
-
-    static constexpr DataType lowerLimit = std::numeric_limits<DataType>::min();
-    static constexpr DataType upperLimit = std::numeric_limits<DataType>::max();
-
-    static Distribution distribution(lowerLimit, upperLimit);
-    static std::default_random_engine generator;
-
-    std::vector<DataType> randomData(size);
-    generate(randomData.begin(), randomData.end(), []() { return distribution(generator); });
-
-    return randomData;
-}
+#pragma message("backendsCommon/test/CommonTestUtils.hpp has been deprecated, it is due for removal in 22.08 release." \
+                " Please use from armnnTestUtils library, /src/armnnTestUtils/CommonTestUtils.hpp)
\ No newline at end of file
diff --git a/src/backends/backendsCommon/test/ComparisonEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ComparisonEndToEndTestImpl.hpp
index e274163..4bdf3f8 100644
--- a/src/backends/backendsCommon/test/ComparisonEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/ComparisonEndToEndTestImpl.hpp
@@ -4,7 +4,7 @@
 //
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp
index 62f0e4c..c8d20da 100644
--- a/src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp
@@ -4,7 +4,7 @@
 //
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/Convolution3dEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/Convolution3dEndToEndTestImpl.hpp
index b1f685b..fab5670 100644
--- a/src/backends/backendsCommon/test/Convolution3dEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/Convolution3dEndToEndTestImpl.hpp
@@ -9,8 +9,8 @@
 
 #include <ResolveType.hpp>
 
-#include <backendsCommon/test/CommonTestUtils.hpp>
-#include <backendsCommon/test/DataLayoutUtils.hpp>
+#include <CommonTestUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
 
 #include <map>
 #include <vector>
diff --git a/src/backends/backendsCommon/test/DataLayoutUtils.hpp b/src/backends/backendsCommon/test/DataLayoutUtils.hpp
index 89b3900..e920c54 100644
--- a/src/backends/backendsCommon/test/DataLayoutUtils.hpp
+++ b/src/backends/backendsCommon/test/DataLayoutUtils.hpp
@@ -1,60 +1,9 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
-#pragma once
+#include <armnnTestUtils/DataLayoutUtils.hpp>
 
-#include <armnn/Tensor.hpp>
-#include <armnn/Types.hpp>
-
-#include <armnnUtils/Permute.hpp>
-
-template<typename T>
-void PermuteTensorNchwToNhwc(armnn::TensorInfo& tensorInfo, std::vector<T>& tensorData)
-{
-    const armnn::PermutationVector nchwToNhwc = { 0, 3, 1, 2 };
-
-    tensorInfo = armnnUtils::Permuted(tensorInfo, nchwToNhwc);
-
-    std::vector<T> tmp(tensorData.size());
-    armnnUtils::Permute(tensorInfo.GetShape(), nchwToNhwc, tensorData.data(), tmp.data(), sizeof(T));
-    tensorData = tmp;
-}
-
-template<typename T>
-void PermuteTensorNhwcToNchw(armnn::TensorInfo& tensorInfo, std::vector<T>& tensorData)
-{
-    const armnn::PermutationVector nhwcToNchw = { 0, 2, 3, 1 };
-
-    tensorInfo = armnnUtils::Permuted(tensorInfo, nhwcToNchw);
-
-    std::vector<T> tmp(tensorData.size());
-    armnnUtils::Permute(tensorInfo.GetShape(), nhwcToNchw, tensorData.data(), tmp.data(), sizeof(T));
-
-    tensorData = tmp;
-}
-
-template<typename T>
-void PermuteTensorNdhwcToNcdhw(armnn::TensorInfo& tensorInfo, std::vector<T>& tensorData)
-{
-    const armnn::PermutationVector ndhwcToNcdhw = { 0, 2, 3, 4, 1 };
-
-    tensorInfo = armnnUtils::Permuted(tensorInfo, ndhwcToNcdhw);
-
-    std::vector<T> tmp(tensorData.size());
-    armnnUtils::Permute(tensorInfo.GetShape(), ndhwcToNcdhw, tensorData.data(), tmp.data(), sizeof(T));
-    tensorData = tmp;
-}
-
-template<typename T>
-void PermuteTensorNcdhwToNdhwc(armnn::TensorInfo& tensorInfo, std::vector<T>& tensorData)
-{
-    const armnn::PermutationVector ncdhwToNdhwc = { 0, 4, 1, 2, 3 };
-
-    tensorInfo = armnnUtils::Permuted(tensorInfo, ncdhwToNdhwc);
-
-    std::vector<T> tmp(tensorData.size());
-    armnnUtils::Permute(tensorInfo.GetShape(), ncdhwToNdhwc, tensorData.data(), tmp.data(), sizeof(T));
-    tensorData = tmp;
-}
+#pragma message("backendsCommon/test/DataLayoutUtils.hpp  has been deprecated, it is due for removal " \
+                "in 22.08 release. Please use public interface include/armnnTestUtils/DataLayoutUtils.hpp")
diff --git a/src/backends/backendsCommon/test/DataTypeUtils.hpp b/src/backends/backendsCommon/test/DataTypeUtils.hpp
index cf97c81..03ee1d2 100644
--- a/src/backends/backendsCommon/test/DataTypeUtils.hpp
+++ b/src/backends/backendsCommon/test/DataTypeUtils.hpp
@@ -1,45 +1,9 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
-#pragma once
+#include "../../armnnTestUtils/DataTypeUtils.hpp"
 
-#include <ResolveType.hpp>
-
-
-#include <reference/workloads/Encoders.hpp>
-
-#include <vector>
-
-// Utility tenmplate to convert a collection of values to the correct type
-template <armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
-std::vector<T> ConvertToDataType(const std::vector<float>& input,
-                                 const armnn::TensorInfo& inputTensorInfo)
-{
-    std::vector<T> output(input.size());
-    auto outputTensorInfo = inputTensorInfo;
-    outputTensorInfo.SetDataType(ArmnnType);
-
-    std::unique_ptr<armnn::Encoder<float>> pOutputEncoder = armnn::MakeEncoder<float>(outputTensorInfo, output.data());
-    armnn::Encoder<float>& rOutputEncoder = *pOutputEncoder;
-
-    for (auto it = input.begin(); it != input.end(); ++it)
-    {
-        rOutputEncoder.Set(*it);
-        ++rOutputEncoder;
-    }
-    return output;
-}
-
-// Utility tenmplate to convert a single value to the correct type
-template <typename T>
-T ConvertToDataType(const float& value,
-                    const armnn::TensorInfo& tensorInfo)
-{
-    std::vector<T> output(1);
-    std::unique_ptr<armnn::Encoder<float>> pEncoder = armnn::MakeEncoder<float>(tensorInfo, output.data());
-    armnn::Encoder<float>& rEncoder = *pEncoder;
-    rEncoder.Set(value);
-    return output[0];
-}
+#pragma message("backendsCommon/test/DataTypeUtils.hpp has been deprecated, it is due for removal in 22.08 release." \
+                " Please use from armnnTestUtils library, /src/armnnTestUtils/DataTypeUtils.hpp)
diff --git a/src/backends/backendsCommon/test/DepthToSpaceEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/DepthToSpaceEndToEndTestImpl.hpp
index b64e618..863d66c 100644
--- a/src/backends/backendsCommon/test/DepthToSpaceEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/DepthToSpaceEndToEndTestImpl.hpp
@@ -10,7 +10,7 @@
 
 #include <QuantizeHelper.hpp>
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/DequantizeEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/DequantizeEndToEndTestImpl.hpp
index fff4c4f..439c083 100644
--- a/src/backends/backendsCommon/test/DequantizeEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/DequantizeEndToEndTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <armnn/INetwork.hpp>
 #include <ResolveType.hpp>
diff --git a/src/backends/backendsCommon/test/DetectionPostProcessEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/DetectionPostProcessEndToEndTestImpl.hpp
index c448886..0f6d2c0 100644
--- a/src/backends/backendsCommon/test/DetectionPostProcessEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/DetectionPostProcessEndToEndTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <armnn/INetwork.hpp>
 #include <ResolveType.hpp>
diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.cpp b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
index 669ce60..72688ad 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.cpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
@@ -5,7 +5,7 @@
 
 #include "DynamicBackendTests.hpp"
 
-#include <test/UnitTests.hpp>
+#include <UnitTests.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/ElementwiseUnaryEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ElementwiseUnaryEndToEndTestImpl.hpp
index 635dc96..3f530cc 100644
--- a/src/backends/backendsCommon/test/ElementwiseUnaryEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/ElementwiseUnaryEndToEndTestImpl.hpp
@@ -4,7 +4,7 @@
 //
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/EndToEndTestImpl.hpp b/src/backends/backendsCommon/test/EndToEndTestImpl.hpp
index 269a460..d326631 100644
--- a/src/backends/backendsCommon/test/EndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/EndToEndTestImpl.hpp
@@ -4,7 +4,7 @@
 //
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <armnn/Descriptors.hpp>
 #include <armnn/INetwork.hpp>
diff --git a/src/backends/backendsCommon/test/FillEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/FillEndToEndTestImpl.hpp
index 27e5aa0..53722e1 100644
--- a/src/backends/backendsCommon/test/FillEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/FillEndToEndTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <armnn/INetwork.hpp>
 #include <armnn/TypesUtils.hpp>
diff --git a/src/backends/backendsCommon/test/FullyConnectedEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/FullyConnectedEndToEndTestImpl.hpp
index 878b6af..1076aa6 100644
--- a/src/backends/backendsCommon/test/FullyConnectedEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/FullyConnectedEndToEndTestImpl.hpp
@@ -4,7 +4,7 @@
 //
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/GatherEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/GatherEndToEndTestImpl.hpp
index 4c67ec2..cf42947 100644
--- a/src/backends/backendsCommon/test/GatherEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/GatherEndToEndTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <armnn/INetwork.hpp>
 #include <ResolveType.hpp>
diff --git a/src/backends/backendsCommon/test/InstanceNormalizationEndToEndTestImpl.cpp b/src/backends/backendsCommon/test/InstanceNormalizationEndToEndTestImpl.cpp
index e715e6b..846aa76 100644
--- a/src/backends/backendsCommon/test/InstanceNormalizationEndToEndTestImpl.cpp
+++ b/src/backends/backendsCommon/test/InstanceNormalizationEndToEndTestImpl.cpp
@@ -12,9 +12,9 @@
 
 #include <armnn/INetwork.hpp>
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
 
-#include <test/TestUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/LayerReleaseConstantDataTest.cpp b/src/backends/backendsCommon/test/LayerReleaseConstantDataTest.cpp
index 579be51..f55a3c3 100644
--- a/src/backends/backendsCommon/test/LayerReleaseConstantDataTest.cpp
+++ b/src/backends/backendsCommon/test/LayerReleaseConstantDataTest.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <Graph.hpp>
 
diff --git a/src/backends/backendsCommon/test/LogSoftmaxEndToEndTestImpl.cpp b/src/backends/backendsCommon/test/LogSoftmaxEndToEndTestImpl.cpp
index 181ecd9..9ffa2a6 100644
--- a/src/backends/backendsCommon/test/LogSoftmaxEndToEndTestImpl.cpp
+++ b/src/backends/backendsCommon/test/LogSoftmaxEndToEndTestImpl.cpp
@@ -8,7 +8,7 @@
 
 #include <armnn/INetwork.hpp>
 
-#include <test/TestUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
index 246cb50..bbae229 100644
--- a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
+++ b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
@@ -4,7 +4,7 @@
 //
 
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 #include "MockBackend.hpp"
 
 #include <armnn/backends/OptimizationViews.hpp>
diff --git a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
index 6c76da6..4dd6bc9 100644
--- a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
+++ b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 #include "MockBackend.hpp"
 #include "MockBackendId.hpp"
 
diff --git a/src/backends/backendsCommon/test/OptimizedNetworkTests.cpp b/src/backends/backendsCommon/test/OptimizedNetworkTests.cpp
index 4b932c7..cc79741 100644
--- a/src/backends/backendsCommon/test/OptimizedNetworkTests.cpp
+++ b/src/backends/backendsCommon/test/OptimizedNetworkTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <Graph.hpp>
 #include <Network.hpp>
diff --git a/src/backends/backendsCommon/test/PreluEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/PreluEndToEndTestImpl.hpp
index c31d084..b361511 100644
--- a/src/backends/backendsCommon/test/PreluEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/PreluEndToEndTestImpl.hpp
@@ -8,7 +8,7 @@
 
 #include <armnn/INetwork.hpp>
 
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/QLstmEndToEndTestImpl.cpp b/src/backends/backendsCommon/test/QLstmEndToEndTestImpl.cpp
index 7c87f35..a01f65e 100644
--- a/src/backends/backendsCommon/test/QLstmEndToEndTestImpl.cpp
+++ b/src/backends/backendsCommon/test/QLstmEndToEndTestImpl.cpp
@@ -5,7 +5,7 @@
 
 #include "QLstmEndToEndTestImpl.hpp"
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 #include "EndToEndTestImpl.hpp"
 
 #include <armnn/INetwork.hpp>
diff --git a/src/backends/backendsCommon/test/QuantizedLstmEndToEndTestImpl.cpp b/src/backends/backendsCommon/test/QuantizedLstmEndToEndTestImpl.cpp
index d481404..8a535d2 100644
--- a/src/backends/backendsCommon/test/QuantizedLstmEndToEndTestImpl.cpp
+++ b/src/backends/backendsCommon/test/QuantizedLstmEndToEndTestImpl.cpp
@@ -5,7 +5,7 @@
 
 #include "QuantizedLstmEndToEndTestImpl.hpp"
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 #include "EndToEndTestImpl.hpp"
 
 #include <ResolveType.hpp>
@@ -15,7 +15,7 @@
 
 #include <armnn/utility/NumericCast.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/RankEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/RankEndToEndTestImpl.hpp
index 5229c47..9dcf705 100644
--- a/src/backends/backendsCommon/test/RankEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/RankEndToEndTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "CommonTestUtils.hpp"
+#include <CommonTestUtils.hpp>
 
 #include <armnn/INetwork.hpp>
 #include <armnn/TypesUtils.hpp>
diff --git a/src/backends/backendsCommon/test/ResizeEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/ResizeEndToEndTestImpl.hpp
index a56db44..94d0a4d 100644
--- a/src/backends/backendsCommon/test/ResizeEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/ResizeEndToEndTestImpl.hpp
@@ -12,7 +12,7 @@
 #include <QuantizeHelper.hpp>
 #include <ResolveType.hpp>
 
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 
 #include <map>
 #include <vector>
diff --git a/src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.cpp b/src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.cpp
index e3b016e..b868ba3 100644
--- a/src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.cpp
+++ b/src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.cpp
@@ -12,9 +12,9 @@
 #include <armnnUtils/Permute.hpp>
 #include <armnnUtils/DataLayoutIndexed.hpp>
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
 
-#include <test/TestUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp
index 3a2af68..b750a7a 100644
--- a/src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp
@@ -10,7 +10,7 @@
 
 #include <armnn/utility/NumericCast.hpp>
 
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/StridedSliceAsyncEndToEndTest.hpp b/src/backends/backendsCommon/test/StridedSliceAsyncEndToEndTest.hpp
index 8ef5ecc..e29782f 100644
--- a/src/backends/backendsCommon/test/StridedSliceAsyncEndToEndTest.hpp
+++ b/src/backends/backendsCommon/test/StridedSliceAsyncEndToEndTest.hpp
@@ -13,7 +13,7 @@
 #include <armnn/IAsyncExecutionCallback.hpp>
 
 #include <AsyncExecutionCallback.hpp>
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/TensorCopyUtils.hpp b/src/backends/backendsCommon/test/TensorCopyUtils.hpp
index d3c8d90..e0aa7a0 100644
--- a/src/backends/backendsCommon/test/TensorCopyUtils.hpp
+++ b/src/backends/backendsCommon/test/TensorCopyUtils.hpp
@@ -1,15 +1,9 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
-#pragma once
 
-#include <armnn/Tensor.hpp>
-
-#include <armnn/backends/ITensorHandle.hpp>
-
-void CopyDataToITensorHandle(armnn::ITensorHandle* tensorHandle, const void* memory);
-
-void CopyDataFromITensorHandle(void* mem, const armnn::ITensorHandle* tensorHandle);
-
-void AllocateAndCopyDataToITensorHandle(armnn::ITensorHandle* tensorHandle, const void* memory);
\ No newline at end of file
+// This file is deprecated and will be removed soon.
+// Please use the new header in armnnTestUtils instead.
+// This will use the new armnnTestUtils header.
+#include <armnnTestUtils/TesnorCopyUtils.hpp>
\ No newline at end of file
diff --git a/src/backends/backendsCommon/test/TransposeConvolution2dEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/TransposeConvolution2dEndToEndTestImpl.hpp
index 8f10869..d1b6945 100644
--- a/src/backends/backendsCommon/test/TransposeConvolution2dEndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/TransposeConvolution2dEndToEndTestImpl.hpp
@@ -12,7 +12,7 @@
 #include <QuantizeHelper.hpp>
 #include <ResolveType.hpp>
 
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 
 #include <map>
 #include <vector>
diff --git a/src/backends/backendsCommon/test/WorkloadDataValidation.cpp b/src/backends/backendsCommon/test/WorkloadDataValidation.cpp
index a19d12f..ee632ff 100644
--- a/src/backends/backendsCommon/test/WorkloadDataValidation.cpp
+++ b/src/backends/backendsCommon/test/WorkloadDataValidation.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "WorkloadTestUtils.hpp"
+#include <WorkloadTestUtils.hpp>
 
 #include <armnn/Exceptions.hpp>
 
diff --git a/src/backends/backendsCommon/test/WorkloadTestUtils.hpp b/src/backends/backendsCommon/test/WorkloadTestUtils.hpp
index 3173561..cb605af 100644
--- a/src/backends/backendsCommon/test/WorkloadTestUtils.hpp
+++ b/src/backends/backendsCommon/test/WorkloadTestUtils.hpp
@@ -1,113 +1,9 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
-#pragma once
 
-#include <armnn/Tensor.hpp>
-
-#include <armnn/backends/IBackendInternal.hpp>
-#include <armnn/backends/IMemoryManager.hpp>
-#include <backendsCommon/Workload.hpp>
-#include <backendsCommon/WorkloadInfo.hpp>
-
-namespace armnn
-{
-class ITensorHandle;
-} // namespace armnn
-
-namespace
-{
-
-template <typename QueueDescriptor>
-void AddInputToWorkload(QueueDescriptor& descriptor,
-    armnn::WorkloadInfo& info,
-    const armnn::TensorInfo& tensorInfo,
-    armnn::ITensorHandle* tensorHandle)
-{
-    descriptor.m_Inputs.push_back(tensorHandle);
-    info.m_InputTensorInfos.push_back(tensorInfo);
-}
-
-template <typename QueueDescriptor>
-void AddOutputToWorkload(QueueDescriptor& descriptor,
-    armnn::WorkloadInfo& info,
-    const armnn::TensorInfo& tensorInfo,
-    armnn::ITensorHandle* tensorHandle)
-{
-    descriptor.m_Outputs.push_back(tensorHandle);
-    info.m_OutputTensorInfos.push_back(tensorInfo);
-}
-
-template <typename QueueDescriptor>
-void SetWorkloadInput(QueueDescriptor& descriptor,
-    armnn::WorkloadInfo& info,
-    unsigned int index,
-    const armnn::TensorInfo& tensorInfo,
-    armnn::ITensorHandle* tensorHandle)
-{
-    descriptor.m_Inputs[index] = tensorHandle;
-    info.m_InputTensorInfos[index] = tensorInfo;
-}
-
-template <typename QueueDescriptor>
-void SetWorkloadOutput(QueueDescriptor& descriptor,
-    armnn::WorkloadInfo& info,
-    unsigned int index,
-    const armnn::TensorInfo& tensorInfo,
-    armnn::ITensorHandle* tensorHandle)
-{
-    descriptor.m_Outputs[index] = tensorHandle;
-    info.m_OutputTensorInfos[index] = tensorInfo;
-}
-
-inline void ExecuteWorkload(armnn::IWorkload& workload,
-                            const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
-                            bool memoryManagementRequested = true)
-{
-    const bool manageMemory = memoryManager && memoryManagementRequested;
-
-    // Acquire working memory (if needed)
-    if (manageMemory)
-    {
-        memoryManager->Acquire();
-    }
-
-    // Perform PostAllocationConfiguration
-    workload.PostAllocationConfigure();
-
-    // Execute the workload
-    workload.Execute();
-
-    // Release working memory (if needed)
-    if (manageMemory)
-    {
-        memoryManager->Release();
-    }
-}
-
-inline armnn::Optional<armnn::DataType> GetBiasTypeFromWeightsType(armnn::Optional<armnn::DataType> weightsType)
-{
-    if (!weightsType)
-    {
-        return weightsType;
-    }
-
-    switch(weightsType.value())
-    {
-        case armnn::DataType::BFloat16:
-        case armnn::DataType::Float16:
-        case armnn::DataType::Float32:
-            return weightsType;
-        case armnn::DataType::QAsymmS8:
-        case armnn::DataType::QAsymmU8:
-        case armnn::DataType::QSymmS8:
-        case armnn::DataType::QSymmS16:
-            return armnn::DataType::Signed32;
-        default:
-            ARMNN_ASSERT_MSG(false, "GetBiasTypeFromWeightsType(): Unsupported data type.");
-    }
-    return armnn::EmptyOptional();
-}
-
-} // anonymous namespace
+// This file is deprecated and will be removed soon.
+// Please use the new header in armnnTestUtils instead.
+// This will use the new armnnTestUtils header.
+#include "../../../armnnTestUtils/WorkloadTestUtils.hpp"
diff --git a/src/backends/backendsCommon/test/layerTests/AbsTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/AbsTestImpl.hpp
index 44dd9ce..7f2d1be 100644
--- a/src/backends/backendsCommon/test/layerTests/AbsTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/AbsTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ActivationTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ActivationTestImpl.cpp
index 5405207..5ec8e13 100644
--- a/src/backends/backendsCommon/test/layerTests/ActivationTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ActivationTestImpl.cpp
@@ -9,13 +9,13 @@
 #include <ResolveType.hpp>
 
 #include <backendsCommon/test/ActivationFixture.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 #include <reference/test/RefWorkloadFactoryHelper.hpp>
 
 #include <armnn/utility/NumericCast.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <algorithm>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ActivationTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ActivationTestImpl.hpp
index a65d97c..9e8b3a2 100644
--- a/src/backends/backendsCommon/test/layerTests/ActivationTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ActivationTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/AdditionTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/AdditionTestImpl.hpp
index b6d6e4a..a66d474 100644
--- a/src/backends/backendsCommon/test/layerTests/AdditionTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/AdditionTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.cpp
index 34b2539..4f82b59 100644
--- a/src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.cpp
@@ -6,11 +6,11 @@
 #include "ArgMinMaxTestImpl.hpp"
 
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.hpp
index 2e7a54b..9414705 100644
--- a/src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.cpp
index 4311faf..90bc8d7 100644
--- a/src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.cpp
@@ -16,10 +16,10 @@
 #include <backendsCommon/WorkloadFactory.hpp>
 #include <reference/test/RefWorkloadFactoryHelper.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.hpp
index f57c061..11bc297 100644
--- a/src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/BatchToSpaceNdTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/BatchToSpaceNdTestImpl.hpp
index 3669281..19d472b 100644
--- a/src/backends/backendsCommon/test/layerTests/BatchToSpaceNdTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/BatchToSpaceNdTestImpl.hpp
@@ -5,19 +5,16 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
-
 #include <ResolveType.hpp>
 
-
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
-
-#include <test/TensorHelpers.hpp>
+#include <armnnTestUtils/LayerTestResult.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <TensorHelpers.hpp>
+#include <WorkloadTestUtils.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/CastTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/CastTestImpl.hpp
index bf8d5a4..5569098 100644
--- a/src/backends/backendsCommon/test/layerTests/CastTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/CastTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.cpp
index b026b4e..598f205 100644
--- a/src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.cpp
@@ -5,9 +5,9 @@
 
 #include "ChannelShuffleTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.hpp
index 3500e72..9c5f40d 100644
--- a/src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.cpp
index 68bc588..5eccd01 100644
--- a/src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.cpp
@@ -13,10 +13,10 @@
 #include <backendsCommon/Workload.hpp>
 #include <backendsCommon/WorkloadData.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.hpp
index 3012417..8a920e5 100644
--- a/src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/ConcatTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ConcatTestImpl.cpp
index 3eca273..5238729 100644
--- a/src/backends/backendsCommon/test/layerTests/ConcatTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ConcatTestImpl.cpp
@@ -11,10 +11,10 @@
 
 #include <armnnUtils/Permute.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 using namespace armnn;
 using namespace armnnUtils;
diff --git a/src/backends/backendsCommon/test/layerTests/ConcatTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ConcatTestImpl.hpp
index 64e0c0a..c91ee86 100644
--- a/src/backends/backendsCommon/test/layerTests/ConcatTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ConcatTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <BFloat16.hpp>
 #include <Half.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/ConstantTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ConstantTestImpl.cpp
index bb827ef..dd339ba 100644
--- a/src/backends/backendsCommon/test/layerTests/ConstantTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ConstantTestImpl.cpp
@@ -13,10 +13,10 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/ConstantTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ConstantTestImpl.hpp
index 71aacb5..34491b1 100644
--- a/src/backends/backendsCommon/test/layerTests/ConstantTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ConstantTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp
index 99f1436..61e000a 100644
--- a/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp
@@ -15,11 +15,11 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <string>
 
diff --git a/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.hpp
index 1f54034..f54a6f8 100644
--- a/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.cpp
index a592ea3..4adc6ef 100644
--- a/src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.cpp
@@ -11,11 +11,11 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 using namespace armnnUtils;
 
diff --git a/src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.hpp
index c612e19..127e7ef 100644
--- a/src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.cpp
index b16ce47..7699daa 100644
--- a/src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.cpp
@@ -5,10 +5,10 @@
 
 #include "ConvertBf16ToFp32TestImpl.hpp"
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 LayerTestResult<float, 4> ConvertBf16ToFp32Test(
     armnn::IWorkloadFactory& workloadFactory,
diff --git a/src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.hpp
index 08f4c04..db92d42 100644
--- a/src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <BFloat16.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.cpp
index 177acef..2c1f9b9 100644
--- a/src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.cpp
@@ -8,10 +8,10 @@
 #include <Half.hpp>
 
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 LayerTestResult<float, 4> SimpleConvertFp16ToFp32Test(
     armnn::IWorkloadFactory& workloadFactory,
diff --git a/src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.hpp
index 8eefb77..9e64cdd 100644
--- a/src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.cpp
index 9ab3746..14a75c1 100644
--- a/src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.cpp
@@ -5,10 +5,10 @@
 
 #include "ConvertFp32ToBf16TestImpl.hpp"
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 LayerTestResult<armnn::BFloat16, 4> ConvertFp32ToBf16Test(
     armnn::IWorkloadFactory& workloadFactory,
diff --git a/src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.hpp
index 9e1da65..737181d 100644
--- a/src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <BFloat16.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.cpp
index 9946801..8210b2d 100644
--- a/src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.cpp
@@ -6,10 +6,10 @@
 #include "ConvertFp32ToFp16TestImpl.hpp"
 
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 LayerTestResult<armnn::Half, 4> SimpleConvertFp32ToFp16Test(
     armnn::IWorkloadFactory& workloadFactory,
diff --git a/src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.hpp
index 39dc8a4..8b6617c 100644
--- a/src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/DebugTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/DebugTestImpl.cpp
index 0539cd1..5475dbf 100644
--- a/src/backends/backendsCommon/test/layerTests/DebugTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/DebugTestImpl.cpp
@@ -9,10 +9,10 @@
 #include <ResolveType.hpp>
 
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/layerTests/DebugTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/DebugTestImpl.hpp
index cf4b237..beab583 100644
--- a/src/backends/backendsCommon/test/layerTests/DebugTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/DebugTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <BFloat16.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp
index 7495c6b..be88e77 100644
--- a/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp
@@ -8,11 +8,11 @@
 #include <QuantizeHelper.hpp>
 
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp
index 18797c6..c6781a9 100644
--- a/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp
@@ -4,7 +4,7 @@
 //
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp
index 924844d..61fb407 100644
--- a/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp
@@ -8,10 +8,10 @@
 #include <ResolveType.hpp>
 
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp
index 1e079a7..8f120d3 100644
--- a/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp
index 2472c34..b9f06de 100644
--- a/src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp
@@ -12,11 +12,11 @@
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
 #include <backendsCommon/test/WorkloadFactoryHelper.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/layerTests/DivisionTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/DivisionTestImpl.hpp
index 4146746..b5d04e5 100644
--- a/src/backends/backendsCommon/test/layerTests/DivisionTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/DivisionTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ElementwiseTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ElementwiseTestImpl.hpp
index 88f34f6..3175aaf 100644
--- a/src/backends/backendsCommon/test/layerTests/ElementwiseTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ElementwiseTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 
 #include <ResolveType.hpp>
@@ -15,11 +15,11 @@
 #include <backendsCommon/WorkloadData.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <memory>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ElementwiseUnaryTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ElementwiseUnaryTestImpl.hpp
index 20e341b..a15add0 100644
--- a/src/backends/backendsCommon/test/layerTests/ElementwiseUnaryTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ElementwiseUnaryTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/ArmNN.hpp>
 
@@ -16,11 +16,11 @@
 #include <backendsCommon/WorkloadData.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <memory>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ExpTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ExpTestImpl.hpp
index 91cb669..c7008a7 100644
--- a/src/backends/backendsCommon/test/layerTests/ExpTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ExpTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.cpp
index bbe4816..f433f9d 100644
--- a/src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.cpp
@@ -8,10 +8,10 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 LayerTestResult<float, 2> FakeQuantizationTest(
     armnn::IWorkloadFactory& workloadFactory,
diff --git a/src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.hpp
index 519880e..d8af8c5 100644
--- a/src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/FillTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/FillTestImpl.cpp
index 9208a31..41fcf59 100644
--- a/src/backends/backendsCommon/test/layerTests/FillTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/FillTestImpl.cpp
@@ -5,11 +5,11 @@
 
 #include "FillTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 template<armnn::DataType ArmnnType, typename T>
 LayerTestResult<T, 4> SimpleFillTest(
diff --git a/src/backends/backendsCommon/test/layerTests/FillTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/FillTestImpl.hpp
index 0eaffd1..beaf35c 100644
--- a/src/backends/backendsCommon/test/layerTests/FillTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/FillTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/FloorTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/FloorTestImpl.cpp
index bf871ae..c05e1d8 100644
--- a/src/backends/backendsCommon/test/layerTests/FloorTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/FloorTestImpl.cpp
@@ -5,11 +5,11 @@
 
 #include "FloorTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 template<armnn::DataType ArmnnType, typename T>
 LayerTestResult<T, 4> SimpleFloorTest(
diff --git a/src/backends/backendsCommon/test/layerTests/FloorTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/FloorTestImpl.hpp
index 78211c6..ff25252 100644
--- a/src/backends/backendsCommon/test/layerTests/FloorTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/FloorTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp
index dcf87fe..59e67fe 100644
--- a/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp
@@ -10,11 +10,11 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 //
 // Implementation templates
diff --git a/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp
index ec921f7..76cea90 100644
--- a/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/GatherTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/GatherTestImpl.cpp
index 51df1eb..edcc900 100644
--- a/src/backends/backendsCommon/test/layerTests/GatherTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/GatherTestImpl.cpp
@@ -8,10 +8,10 @@
 #include <ResolveType.hpp>
 
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/GatherTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/GatherTestImpl.hpp
index 8c37f92..363478d 100644
--- a/src/backends/backendsCommon/test/layerTests/GatherTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/GatherTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.cpp
index ed656da..da9608c 100644
--- a/src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.cpp
@@ -13,11 +13,11 @@
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.hpp
index d28069a..be77144 100644
--- a/src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.cpp
index 11c9766..67f1c3c 100644
--- a/src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.cpp
@@ -11,10 +11,10 @@
 #include <armnnUtils/TensorUtils.hpp>
 #include <armnnUtils/Permute.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <numeric>
 
diff --git a/src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.hpp
index 137ab7e..283a25b 100644
--- a/src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/Types.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/LayerTestResult.hpp b/src/backends/backendsCommon/test/layerTests/LayerTestResult.hpp
index ac60764..e0054ca 100644
--- a/src/backends/backendsCommon/test/layerTests/LayerTestResult.hpp
+++ b/src/backends/backendsCommon/test/layerTests/LayerTestResult.hpp
@@ -1,62 +1,15 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
-#pragma once
+// This file is deprecated and will be removed soon.
+// Please use the new header in armnnTestUtils instead.
+// This will use the new armnnTestUtils header.
+#include <armnnTestUtils/LayerTestResult.hpp>
 
-#include <armnn/Tensor.hpp>
-#include <armnn/utility/Assert.hpp>
-
-#include <cstddef>
-#include <vector>
-
-template <typename T, std::size_t n>
-struct LayerTestResult
-{
-    LayerTestResult(const armnn::TensorInfo& outputInfo)
-        : m_Supported(true)
-        , m_CompareBoolean(false)
-    {
-        m_ActualData.reserve(outputInfo.GetNumElements());
-        m_ExpectedData.reserve(outputInfo.GetNumElements());
-        m_ActualShape = outputInfo.GetShape();
-        m_ExpectedShape = outputInfo.GetShape();
-    }
-
-    LayerTestResult(const std::vector<T>& actualData,
-                    const std::vector<T>& expectedData,
-                    const armnn::TensorShape& actualShape,
-                    const armnn::TensorShape& expectedShape)
-        : m_ActualData(actualData)
-        , m_ExpectedData(expectedData)
-        , m_ActualShape(actualShape)
-        , m_ExpectedShape(expectedShape)
-        , m_Supported(true)
-        , m_CompareBoolean(false)
-    {}
-
-    LayerTestResult(const std::vector<T>& actualData,
-                    const std::vector<T>& expectedData,
-                    const armnn::TensorShape& actualShape,
-                    const armnn::TensorShape& expectedShape,
-                    const bool compareBoolean)
-        : m_ActualData(actualData)
-        , m_ExpectedData(expectedData)
-        , m_ActualShape(actualShape)
-        , m_ExpectedShape(expectedShape)
-        , m_Supported(true)
-        , m_CompareBoolean(compareBoolean)
-    {}
-
-    std::vector<T> m_ActualData;
-    std::vector<T> m_ExpectedData;
-    armnn::TensorShape m_ActualShape;
-    armnn::TensorShape m_ExpectedShape;
-
-    bool m_Supported;
-    bool m_CompareBoolean;
-};
+#pragma message("backendsCommon/test/layerTests/LayerTestResult.hpp has been deprecated, it is due for " \
+                "removal in 22.08 release. Please use public interface include/armnnTestUtils/LayerTestResult.hpp")
 
 
 
diff --git a/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp
index ad23f8f..94f5a5b 100644
--- a/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp
@@ -14,10 +14,10 @@
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.hpp
index 1f4cc89..b293337 100644
--- a/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/LogTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/LogTestImpl.hpp
index e7e14b8..cf9878f 100644
--- a/src/backends/backendsCommon/test/layerTests/LogTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/LogTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/LogicalTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/LogicalTestImpl.cpp
index 119e76b..a2ce5af 100644
--- a/src/backends/backendsCommon/test/layerTests/LogicalTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/LogicalTestImpl.cpp
@@ -11,10 +11,10 @@
 #include <backendsCommon/Workload.hpp>
 #include <backendsCommon/WorkloadData.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace {
 
diff --git a/src/backends/backendsCommon/test/layerTests/LogicalTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/LogicalTestImpl.hpp
index 1711d90..b81d2f3 100644
--- a/src/backends/backendsCommon/test/layerTests/LogicalTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/LogicalTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/LstmTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/LstmTestImpl.cpp
index 035c592..56bc23c 100644
--- a/src/backends/backendsCommon/test/layerTests/LstmTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/LstmTestImpl.cpp
@@ -11,14 +11,14 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
 #include <reference/workloads/Decoders.hpp>
 #include <reference/workloads/Encoders.hpp>
 #include <reference/workloads/LstmUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <doctest/doctest.h>
 namespace
diff --git a/src/backends/backendsCommon/test/layerTests/LstmTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/LstmTestImpl.hpp
index d27ddd6..62bb125 100644
--- a/src/backends/backendsCommon/test/layerTests/LstmTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/LstmTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/MaximumTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/MaximumTestImpl.hpp
index 8cc660b..c13059b 100644
--- a/src/backends/backendsCommon/test/layerTests/MaximumTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/MaximumTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/MeanTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/MeanTestImpl.hpp
index 0f045d1..9cc45e2 100644
--- a/src/backends/backendsCommon/test/layerTests/MeanTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/MeanTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/MinimumTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/MinimumTestImpl.hpp
index 1e84191..bd60b20 100644
--- a/src/backends/backendsCommon/test/layerTests/MinimumTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/MinimumTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.cpp
index 61899db..60fbfb0 100644
--- a/src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.cpp
@@ -7,10 +7,10 @@
 
 #include <QuantizeHelper.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 //
 // Implementation templates
diff --git a/src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.hpp
index 52898b8..60475fd 100644
--- a/src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/MultiplicationTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/MultiplicationTestImpl.hpp
index 9d2a954..72154db 100644
--- a/src/backends/backendsCommon/test/layerTests/MultiplicationTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/MultiplicationTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/NegTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/NegTestImpl.hpp
index 126a754..0296ca2 100644
--- a/src/backends/backendsCommon/test/layerTests/NegTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/NegTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.cpp
index 153afd9..e3a3bea 100644
--- a/src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.cpp
@@ -12,10 +12,10 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.hpp
index bbbbc4f..30cd57c 100644
--- a/src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/Types.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/PadTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/PadTestImpl.cpp
index a09e387..628eed0 100644
--- a/src/backends/backendsCommon/test/layerTests/PadTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/PadTestImpl.cpp
@@ -7,10 +7,10 @@
 
 #include <QuantizeHelper.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 //
 // Implementation templates
diff --git a/src/backends/backendsCommon/test/layerTests/PadTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/PadTestImpl.hpp
index 4c30c42..1d19aa8 100644
--- a/src/backends/backendsCommon/test/layerTests/PadTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/PadTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/PermuteTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/PermuteTestImpl.hpp
index 91add54..26fb504 100644
--- a/src/backends/backendsCommon/test/layerTests/PermuteTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/PermuteTestImpl.hpp
@@ -11,9 +11,9 @@
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 template<typename T>
 LayerTestResult<T, 4> SimplePermuteTestImpl(
diff --git a/src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.cpp
index 1eaf1f9..7bb0e59 100644
--- a/src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.cpp
@@ -19,10 +19,10 @@
 
 #include <backendsCommon/WorkloadInfo.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.hpp
index bf2c39e..0a25339 100644
--- a/src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/Types.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.cpp
index 96a56fd..ad438ea 100644
--- a/src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.cpp
@@ -19,10 +19,10 @@
 #include <armnn/BackendHelper.hpp>
 #include <backendsCommon/WorkloadInfo.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.hpp
index e7cd6b4..6c1d5de 100644
--- a/src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/Types.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/PreluTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/PreluTestImpl.hpp
index 3cf8581..6b9aaed 100644
--- a/src/backends/backendsCommon/test/layerTests/PreluTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/PreluTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <QuantizeHelper.hpp>
 #include <ResolveType.hpp>
@@ -14,11 +14,11 @@
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
 #include <backendsCommon/test/WorkloadFactoryHelper.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
 LayerTestResult<T, 4> PreluTest(
diff --git a/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp
index 029d50e..b593620 100644
--- a/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp
@@ -11,10 +11,10 @@
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp
index 9e2f3df..9671550 100644
--- a/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/RankTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/RankTestImpl.cpp
index c483d2c..c04d7b2 100644
--- a/src/backends/backendsCommon/test/layerTests/RankTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/RankTestImpl.cpp
@@ -5,11 +5,11 @@
 
 #include "RankTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 template<typename T, std::size_t n>
 LayerTestResult<int32_t, 1> RankTest(
diff --git a/src/backends/backendsCommon/test/layerTests/RankTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/RankTestImpl.hpp
index 0aacee1..27b0fcc 100644
--- a/src/backends/backendsCommon/test/layerTests/RankTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/RankTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.cpp
index 4fb0732..b93eb55 100644
--- a/src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.cpp
@@ -5,11 +5,11 @@
 
 #include "ReduceProdTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.hpp
index 97e9497..4d7ddde 100644
--- a/src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.cpp
index 9f5422b..c50fe75 100644
--- a/src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.cpp
@@ -5,11 +5,11 @@
 
 #include "ReduceSumTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.hpp
index db23240..a5249b4 100644
--- a/src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ReductionTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ReductionTestImpl.cpp
index 7ce03ad..a69afb8 100644
--- a/src/backends/backendsCommon/test/layerTests/ReductionTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ReductionTestImpl.cpp
@@ -5,11 +5,11 @@
 
 #include "ReductionTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <iostream>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ReductionTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ReductionTestImpl.hpp
index 495a74b..1480935 100644
--- a/src/backends/backendsCommon/test/layerTests/ReductionTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ReductionTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.cpp
index c3aacad..ccf2345 100644
--- a/src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.cpp
@@ -5,11 +5,11 @@
 
 #include "ReshapeTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.hpp
index a29a965..c692c95 100644
--- a/src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ResizeTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ResizeTestImpl.cpp
index 7706bde..aa5bbae 100644
--- a/src/backends/backendsCommon/test/layerTests/ResizeTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ResizeTestImpl.cpp
@@ -12,11 +12,11 @@
 #include <armnnUtils/DataLayoutIndexed.hpp>
 #include <armnnUtils/Permute.hpp>
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/ResizeTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ResizeTestImpl.hpp
index ce7d419..bbbe861 100644
--- a/src/backends/backendsCommon/test/layerTests/ResizeTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ResizeTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/RsqrtTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/RsqrtTestImpl.hpp
index 0df9ea7..33d965b 100644
--- a/src/backends/backendsCommon/test/layerTests/RsqrtTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/RsqrtTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/ShapeTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ShapeTestImpl.cpp
index d6c0314..3ebb523 100644
--- a/src/backends/backendsCommon/test/layerTests/ShapeTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/ShapeTestImpl.cpp
@@ -5,11 +5,11 @@
 
 #include "ShapeTestImpl.hpp"
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <DataTypeUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 template<typename T, std::size_t n>
 LayerTestResult<int32_t, 1> ShapeTest(
diff --git a/src/backends/backendsCommon/test/layerTests/ShapeTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/ShapeTestImpl.hpp
index 85f7c0a..8b95aa5 100644
--- a/src/backends/backendsCommon/test/layerTests/ShapeTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/ShapeTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/SinTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/SinTestImpl.hpp
index b04d75a..ee7bcb9 100644
--- a/src/backends/backendsCommon/test/layerTests/SinTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/SinTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/SliceTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/SliceTestImpl.cpp
index f3e2836..ddf216d 100644
--- a/src/backends/backendsCommon/test/layerTests/SliceTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/SliceTestImpl.cpp
@@ -9,10 +9,10 @@
 #include <ResolveType.hpp>
 
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/SliceTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/SliceTestImpl.hpp
index d308268..c4d62cc 100644
--- a/src/backends/backendsCommon/test/layerTests/SliceTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/SliceTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.cpp
index 375bdaa..05c4784 100644
--- a/src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.cpp
@@ -11,10 +11,10 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <algorithm>
 
diff --git a/src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.hpp
index f0efe4d..9f93c02 100644
--- a/src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.cpp
index 44a37f4..69f5f5a 100644
--- a/src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.cpp
@@ -11,10 +11,10 @@
 
 #include <armnnUtils/Permute.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.hpp
index 69ee99b..1f446b7 100644
--- a/src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.hpp
@@ -4,7 +4,7 @@
 //
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.cpp
index 9175aec..d8c5747 100644
--- a/src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.cpp
@@ -11,10 +11,10 @@
 
 #include <armnnUtils/Permute.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.hpp
index 29f2646..5a3e493 100644
--- a/src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.hpp
@@ -4,7 +4,7 @@
 //
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/SplitterTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/SplitterTestImpl.cpp
index e19a321..bf95a9f 100644
--- a/src/backends/backendsCommon/test/layerTests/SplitterTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/SplitterTestImpl.cpp
@@ -9,10 +9,10 @@
 #include <ResolveType.hpp>
 
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/SplitterTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/SplitterTestImpl.hpp
index 4007200..dc76bc9 100644
--- a/src/backends/backendsCommon/test/layerTests/SplitterTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/SplitterTestImpl.hpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/StackTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/StackTestImpl.cpp
index 25989f9..2a0e049 100644
--- a/src/backends/backendsCommon/test/layerTests/StackTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/StackTestImpl.cpp
@@ -4,7 +4,7 @@
 //
 
 #include "StackTestImpl.hpp"
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
@@ -12,10 +12,10 @@
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/StackTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/StackTestImpl.hpp
index 75e9ae8..24e88c4 100644
--- a/src/backends/backendsCommon/test/layerTests/StackTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/StackTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.cpp
index af4b089..72ba681 100644
--- a/src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.cpp
@@ -9,10 +9,10 @@
 #include <ResolveType.hpp>
 
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 namespace
 {
diff --git a/src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.hpp
index 52feb0c..3806d33 100644
--- a/src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/backendsCommon/test/layerTests/SubtractionTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/SubtractionTestImpl.hpp
index 6113b02..eba0d0a 100644
--- a/src/backends/backendsCommon/test/layerTests/SubtractionTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/SubtractionTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <Half.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.cpp
index dae7483..34abc86 100644
--- a/src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.cpp
@@ -12,13 +12,13 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/DataLayoutUtils.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
 #include <reference/RefWorkloadFactory.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.hpp
index 0c45b0f..6af9e32 100644
--- a/src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/TransposeTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/TransposeTestImpl.hpp
index 6be8bcb..dceb386 100644
--- a/src/backends/backendsCommon/test/layerTests/TransposeTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/TransposeTestImpl.hpp
@@ -12,9 +12,9 @@
 #include <backendsCommon/WorkloadFactory.hpp>
 
 #include <backendsCommon/test/WorkloadFactoryHelper.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 template<typename T>
 LayerTestResult<T, 4> SimpleTransposeTestImpl(
diff --git a/src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.cpp
index d17dceb..5315dd3 100644
--- a/src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.cpp
@@ -9,8 +9,8 @@
 
 #include <backendsCommon/TensorHandle.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
 #include <ResolveType.hpp>
 
diff --git a/src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.hpp
index 20ac313..88b09b9 100644
--- a/src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.hpp
+++ b/src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "LayerTestResult.hpp"
+#include <armnnTestUtils/LayerTestResult.hpp>
 
 #include <armnn/backends/IBackendInternal.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
diff --git a/src/backends/cl/test/CMakeLists.txt b/src/backends/cl/test/CMakeLists.txt
index 8ee532a..af116a4 100644
--- a/src/backends/cl/test/CMakeLists.txt
+++ b/src/backends/cl/test/CMakeLists.txt
@@ -37,6 +37,7 @@
 add_library(armnnClBackendUnitTests OBJECT ${armnnClBackendUnitTests_sources})
 target_include_directories(armnnClBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
 target_include_directories(armnnClBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
+target_include_directories(armnnClBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnTestUtils)
 target_include_directories(armnnClBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
 target_include_directories(armnnClBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
 target_include_directories(armnnClBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
diff --git a/src/backends/cl/test/ClCreateWorkloadTests.cpp b/src/backends/cl/test/ClCreateWorkloadTests.cpp
index 4e40328..dd53f38 100644
--- a/src/backends/cl/test/ClCreateWorkloadTests.cpp
+++ b/src/backends/cl/test/ClCreateWorkloadTests.cpp
@@ -10,8 +10,8 @@
 #include <armnn/utility/IgnoreUnused.hpp>
 #include <armnn/utility/PolymorphicDowncast.hpp>
 #include <backendsCommon/MemCopyWorkload.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
 #include <aclCommon/test/CreateWorkloadClNeon.hpp>
 #include <aclCommon/ArmComputeTensorUtils.hpp>
diff --git a/src/backends/cl/test/ClFallbackTests.cpp b/src/backends/cl/test/ClFallbackTests.cpp
index cfe2b36..6ac9433 100644
--- a/src/backends/cl/test/ClFallbackTests.cpp
+++ b/src/backends/cl/test/ClFallbackTests.cpp
@@ -3,9 +3,9 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 
-#include <test/GraphUtils.hpp>
+#include <GraphUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/cl/test/ClLayerSupportTests.cpp b/src/backends/cl/test/ClLayerSupportTests.cpp
index b18da11..1747cb6 100644
--- a/src/backends/cl/test/ClLayerSupportTests.cpp
+++ b/src/backends/cl/test/ClLayerSupportTests.cpp
@@ -8,7 +8,7 @@
 #include <layers/ConvertFp16ToFp32Layer.hpp>
 #include <layers/ConvertFp32ToFp16Layer.hpp>
 #include <layers/MeanLayer.hpp>
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <backendsCommon/TensorHandle.hpp>
 #include <cl/ClWorkloadFactory.hpp>
diff --git a/src/backends/cl/test/ClLayerTests.cpp b/src/backends/cl/test/ClLayerTests.cpp
index 6c27d51..967a7e4 100644
--- a/src/backends/cl/test/ClLayerTests.cpp
+++ b/src/backends/cl/test/ClLayerTests.cpp
@@ -6,8 +6,8 @@
 #include "ClContextControlFixture.hpp"
 #include "ClWorkloadFactoryHelper.hpp"
 
-#include "test/TensorHelpers.hpp"
-#include "test/UnitTests.hpp"
+#include <TensorHelpers.hpp>
+#include <UnitTests.hpp>
 
 #include <cl/ClLayerSupport.hpp>
 #include <cl/ClWorkloadFactory.hpp>
diff --git a/src/backends/cl/test/ClOptimizedNetworkTests.cpp b/src/backends/cl/test/ClOptimizedNetworkTests.cpp
index 4c2a474..cf17eae 100644
--- a/src/backends/cl/test/ClOptimizedNetworkTests.cpp
+++ b/src/backends/cl/test/ClOptimizedNetworkTests.cpp
@@ -7,7 +7,7 @@
 
 #include <Network.hpp>
 
-#include <test/GraphUtils.hpp>
+#include <GraphUtils.hpp>
 
 #include <cl/ClWorkloadFactory.hpp>
 #include <cl/ClBackendContext.hpp>
diff --git a/src/backends/cl/test/OpenClTimerTest.cpp b/src/backends/cl/test/OpenClTimerTest.cpp
index 0da1db7..85fdc81 100644
--- a/src/backends/cl/test/OpenClTimerTest.cpp
+++ b/src/backends/cl/test/OpenClTimerTest.cpp
@@ -7,7 +7,7 @@
 
 #include "ClWorkloadFactoryHelper.hpp"
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <backendsCommon/TensorHandle.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
@@ -16,8 +16,8 @@
 #include <cl/ClWorkloadFactory.hpp>
 #include <cl/OpenClTimer.hpp>
 
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
 #include <arm_compute/runtime/CL/CLScheduler.h>
 
diff --git a/src/backends/neon/test/CMakeLists.txt b/src/backends/neon/test/CMakeLists.txt
index 9a45b7d..e4c5b34 100644
--- a/src/backends/neon/test/CMakeLists.txt
+++ b/src/backends/neon/test/CMakeLists.txt
@@ -53,6 +53,7 @@
 add_library(armnnNeonBackendUnitTests OBJECT ${armnnNeonBackendUnitTests_sources})
 target_include_directories(armnnNeonBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
 target_include_directories(armnnNeonBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
+target_include_directories(armnnNeonBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnTestUtils)
 target_include_directories(armnnNeonBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
 target_include_directories(armnnNeonBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
 target_include_directories(armnnNeonBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
diff --git a/src/backends/neon/test/NeonFallbackTests.cpp b/src/backends/neon/test/NeonFallbackTests.cpp
index ae6cfae..d2de843 100644
--- a/src/backends/neon/test/NeonFallbackTests.cpp
+++ b/src/backends/neon/test/NeonFallbackTests.cpp
@@ -3,10 +3,10 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 #include <backendsCommon/test/mockBackend/MockImportBackend.hpp>
 
-#include <test/GraphUtils.hpp>
+#include <GraphUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/neon/test/NeonLayerSupportTests.cpp b/src/backends/neon/test/NeonLayerSupportTests.cpp
index 494c8f9..fbb91a9 100644
--- a/src/backends/neon/test/NeonLayerSupportTests.cpp
+++ b/src/backends/neon/test/NeonLayerSupportTests.cpp
@@ -7,7 +7,7 @@
 
 #include <layers/ConvertFp16ToFp32Layer.hpp>
 #include <layers/ConvertFp32ToFp16Layer.hpp>
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <backendsCommon/TensorHandle.hpp>
 #include <neon/NeonWorkloadFactory.hpp>
diff --git a/src/backends/neon/test/NeonLayerTests.cpp b/src/backends/neon/test/NeonLayerTests.cpp
index 1750f24..3b63a88 100644
--- a/src/backends/neon/test/NeonLayerTests.cpp
+++ b/src/backends/neon/test/NeonLayerTests.cpp
@@ -5,8 +5,8 @@
 
 #include "NeonWorkloadFactoryHelper.hpp"
 
-#include <test/TensorHelpers.hpp>
-#include <test/UnitTests.hpp>
+#include <TensorHelpers.hpp>
+#include <UnitTests.hpp>
 
 #include <neon/NeonLayerSupport.hpp>
 #include <neon/NeonWorkloadFactory.hpp>
diff --git a/src/backends/neon/test/NeonLayerTests_NDK_Bug.cpp b/src/backends/neon/test/NeonLayerTests_NDK_Bug.cpp
index 5a65b15..2410960 100644
--- a/src/backends/neon/test/NeonLayerTests_NDK_Bug.cpp
+++ b/src/backends/neon/test/NeonLayerTests_NDK_Bug.cpp
@@ -5,8 +5,9 @@
 
 #include "NeonWorkloadFactoryHelper.hpp"
 
+#include <UnitTests.hpp>
+#include <backendsCommon/test/LayerTests.hpp>
 #include <neon/NeonWorkloadFactory.hpp>
-#include <test/UnitTests.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/neon/test/NeonTensorHandleTests.cpp b/src/backends/neon/test/NeonTensorHandleTests.cpp
index 685a074..9d69a5c 100644
--- a/src/backends/neon/test/NeonTensorHandleTests.cpp
+++ b/src/backends/neon/test/NeonTensorHandleTests.cpp
@@ -11,9 +11,9 @@
 #include <armnn/utility/NumericCast.hpp>
 #include <armnn/utility/PolymorphicDowncast.hpp>
 
-#include <test/GraphUtils.hpp>
+#include <GraphUtils.hpp>
 #include <arm_compute/runtime/Allocator.h>
-#include <backendsCommon/test/CommonTestUtils.hpp>
+#include <CommonTestUtils.hpp>
 
 #include <doctest/doctest.h>
 #include <armnn/utility/Assert.hpp>
diff --git a/src/backends/neon/test/NeonTimerTest.cpp b/src/backends/neon/test/NeonTimerTest.cpp
index 87e1567..3596dfa 100644
--- a/src/backends/neon/test/NeonTimerTest.cpp
+++ b/src/backends/neon/test/NeonTimerTest.cpp
@@ -6,7 +6,7 @@
 #include "NeonWorkloadFactoryHelper.hpp"
 
 
-#include <test/TensorHelpers.hpp>
+#include <TensorHelpers.hpp>
 
 #include <backendsCommon/TensorHandle.hpp>
 #include <backendsCommon/WorkloadFactory.hpp>
@@ -15,8 +15,8 @@
 #include <neon/NeonWorkloadFactory.hpp>
 
 #include <backendsCommon/test/LayerTests.hpp>
-#include <backendsCommon/test/TensorCopyUtils.hpp>
-#include <backendsCommon/test/WorkloadTestUtils.hpp>
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <WorkloadTestUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/reference/test/CMakeLists.txt b/src/backends/reference/test/CMakeLists.txt
index d7c5da8..d5ce355 100644
--- a/src/backends/reference/test/CMakeLists.txt
+++ b/src/backends/reference/test/CMakeLists.txt
@@ -23,6 +23,7 @@
 add_library(armnnRefBackendUnitTests OBJECT ${armnnRefBackendUnitTests_sources})
 target_include_directories(armnnRefBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
 target_include_directories(armnnRefBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
+target_include_directories(armnnRefBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnTestUtils)
 target_include_directories(armnnRefBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
 target_include_directories(armnnRefBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
 target_include_directories(armnnRefBackendUnitTests PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
diff --git a/src/backends/reference/test/RefCreateWorkloadTests.cpp b/src/backends/reference/test/RefCreateWorkloadTests.cpp
index fae8d0c..e865f25 100644
--- a/src/backends/reference/test/RefCreateWorkloadTests.cpp
+++ b/src/backends/reference/test/RefCreateWorkloadTests.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include <test/CreateWorkload.hpp>
+#include <CreateWorkload.hpp>
 
 #include <armnn/utility/PolymorphicDowncast.hpp>
 #include <reference/RefTensorHandle.hpp>
diff --git a/src/backends/reference/test/RefLayerSupportTests.cpp b/src/backends/reference/test/RefLayerSupportTests.cpp
index 1adc54e..f0eb62f 100644
--- a/src/backends/reference/test/RefLayerSupportTests.cpp
+++ b/src/backends/reference/test/RefLayerSupportTests.cpp
@@ -5,7 +5,8 @@
 
 #include <layers/ConvertFp16ToFp32Layer.hpp>
 #include <layers/ConvertFp32ToFp16Layer.hpp>
-#include <test/TensorHelpers.hpp>
+
+#include <TensorHelpers.hpp>
 
 #include <backendsCommon/TensorHandle.hpp>
 #include <reference/RefWorkloadFactory.hpp>
diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp
index 13487dd..9f5814b 100644
--- a/src/backends/reference/test/RefLayerTests.cpp
+++ b/src/backends/reference/test/RefLayerTests.cpp
@@ -9,7 +9,7 @@
 
 #include <reference/RefWorkloadFactory.hpp>
 
-#include <test/UnitTests.hpp>
+#include <UnitTests.hpp>
 
 TEST_SUITE("Compute_Reference")
 {
diff --git a/src/backends/reference/test/RefOptimizedNetworkTests.cpp b/src/backends/reference/test/RefOptimizedNetworkTests.cpp
index 578d667..5b128a1 100644
--- a/src/backends/reference/test/RefOptimizedNetworkTests.cpp
+++ b/src/backends/reference/test/RefOptimizedNetworkTests.cpp
@@ -7,7 +7,7 @@
 #include <Network.hpp>
 
 #include <reference/RefWorkloadFactory.hpp>
-#include <test/GraphUtils.hpp>
+#include <GraphUtils.hpp>
 
 #include <doctest/doctest.h>
 
diff --git a/src/backends/reference/workloads/RefChannelShuffleWorkload.cpp b/src/backends/reference/workloads/RefChannelShuffleWorkload.cpp
index 6571715..9f8514d 100644
--- a/src/backends/reference/workloads/RefChannelShuffleWorkload.cpp
+++ b/src/backends/reference/workloads/RefChannelShuffleWorkload.cpp
@@ -3,7 +3,6 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include <backendsCommon/test/DataTypeUtils.hpp>
 #include <armnn/backends/ITensorHandleFactory.hpp>
 #include <armnnUtils/Transpose.hpp>
 #include "RefChannelShuffleWorkload.hpp"
diff --git a/src/profiling/test/ProfilingTestUtils.cpp b/src/profiling/test/ProfilingTestUtils.cpp
index e0d3dd7..51f27d4 100644
--- a/src/profiling/test/ProfilingTestUtils.cpp
+++ b/src/profiling/test/ProfilingTestUtils.cpp
@@ -16,7 +16,7 @@
 
 #include <common/include/LabelsAndEventClasses.hpp>
 
-#include <test/TestUtils.hpp>
+#include <TestUtils.hpp>
 
 #include <doctest/doctest.h>